首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回相同实例的TinyIoC

返回相同实例的TinyIoC
EN

Stack Overflow用户
提问于 2013-07-12 10:04:44
回答 2查看 646关注 0票数 0

我刚接触依赖注入模式,在tinyioc中从container.Resolve获取类的新实例时遇到了问题,它只是不断返回相同的实例,而不是新的实例。现在来看代码

代码语言:javascript
复制
public abstract class HObjectBase : Object
{
    private string _name = String.Empty;
    public string Name 
    {
        get
        {
            return this._name;
        }
        set
        {
            if (this._name == string.Empty && value.Length > 0 && value != String.Empty)
                this._name = value;
            else if (value.Length < 1 && value == String.Empty)
                throw new FieldAccessException("Objects names cannot be blank");
            else
                throw new FieldAccessException("Once the internal name of an object has been set it cannot be changed");
        }
    }

    private Guid _id = new Guid();
    public Guid Id 
    {
        get
        {
            return this._id;
        }
        set
        {
            if (this._id == new Guid())
                this._id = value;
            else
                throw new FieldAccessException("Once the internal id of an object has been set it cannot be changed");

        }
    }

    private HObjectBase _parent = null;
    public HObjectBase Parent 
    {
        get
        {
            return this._parent;
        }
        set
        {
            if (this._parent == null)
                this._parent = value;
            else
                throw new FieldAccessException("Once the parent of an object has been set it cannot be changed");
        }
    }
}

public abstract class HZoneBase : HObjectBase
{
    public new HObjectBase Parent
    {
        get
        {
            return base.Parent;
        }
        set
        {
            if (value == null || value.GetType() == typeof(HZoneBase))
            {
                base.Parent = value;
            }
            else
            {
                throw new FieldAccessException("Zones may only have other zones as parents");
            }
        }
    }


    private IHMetaDataStore _store;
    public HZoneBase(IHMetaDataStore store)
    {
        this._store = store;
    }



    public void Save()
    {
        this._store.SaveZone(this);
    }
}

而派生类目前是一个哑元,但它在这里

代码语言:javascript
复制
public class HZone : HZoneBase
{
    public HZone(IHMetaDataStore store)
        : base(store)
    {
    }
}

现在,因为这是一个外部库,所以我有一个用于访问所有内容的面向对象的类

代码语言:javascript
复制
public class Hadrian 
{
    private TinyIoCContainer _container;

    public Hadrian(IHMetaDataStore store)
    {
        this._container = new TinyIoCContainer();
        this._container.Register(store);
        this._container.AutoRegister();
    }

    public HZoneBase NewZone()
    {
        return _container.Resolve<HZoneBase>();
    }

    public HZoneBase GetZone(Guid id)
    {
        var metadataStore = this._container.Resolve<IHMetaDataStore>();
        return metadataStore.GetZone(id);
    }

    public List<HZoneBase> ListRootZones()
    {
        var metadataStore = this._container.Resolve<IHMetaDataStore>();
        return metadataStore.ListRootZones();
    }
}

然而,测试失败了,因为Hadrian类上的GetNewZone()方法一直返回相同的实例。

测试代码

代码语言:javascript
复制
[Fact]
public void ListZones()
{
    Hadrian instance = new Hadrian(new MemoryMetaDataStore());
    Guid[] guids = { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
    int cnt = 0;
    foreach (Guid guid in guids)
    {
        HZone zone = (HZone)instance.NewZone();
        zone.Id = guids[cnt];
        zone.Name = "Testing" + cnt.ToString();
        zone.Parent = null;
        zone.Save();
        cnt++;
    }

    cnt = 0;
    foreach (HZone zone in instance.ListRootZones())
    {
        Assert.Equal(zone.Id, guids[cnt]);
        Assert.Equal(zone.Name, "Testing" + cnt.ToString());
        Assert.Equal(zone.Parent, null);
    }
}

我知道这可能是我在模式中遗漏了一些简单的东西,但我不确定,任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-13 07:57:31

首先,请始终将代码简化为演示问题所必需的代码,但要提供足够的代码才能真正运行;我必须猜测MemoryMetaDataStore做什么并自己实现它才能运行代码。

另外,请说在哪里失败,在哪里失败,让其他人直接指出问题所在。我花了几分钟弄清楚,我得到的异常是你的问题,而你甚至没有进入断言。

也就是说,container.Resolve<HZoneBase>()将始终返回相同的实例,因为这就是TinyIoC中自动注册的工作方式-一旦解析了抽象,后续调用总是会返回相同的实例。

要更改这一点,请将以下行添加到Hadrian构造函数中:

代码语言:javascript
复制
this._container.Register<HZoneBase, HZone>().AsMultiInstance();

这将告诉容器为HZoneBase的每个解析请求创建一个新实例。

另外,Bassetassen关于断言部分的回答是正确的。

一般来说,如果你想学习依赖注入,你应该读一读Mark Seemann的优秀著作“.NET中的依赖注入”--这不是一本容易读的书,因为整个主题本身就很复杂,但它非常值得,而且会让你比自己学习它快几年。

票数 7
EN

Stack Overflow用户

发布于 2013-07-12 22:37:26

在断言阶段,您不会递增cnt。您还可以在断言中使用实际值作为期望值。这将会令人困惑,因为它说某些东西是预期的,而它实际上是返回的实际值。

断言部分应该是:

代码语言:javascript
复制
cnt = 0;
foreach (HZone zone in instance.ListRootZones())
{
    Assert.Equal(guids[cnt], zone.Id);
    Assert.Equal("Testing" + cnt.ToString(), zone.Name);
    Assert.Equal(null, zone.Parent);
    cnt++;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17606404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档