【问题标题】:TinyIoC Returning Same instanceTinyIoC 返回相同的实例
【发布时间】:2013-07-13 07:57:30
【问题描述】:

我是依赖注入模式的新手,我在从容器中获取类的新实例时遇到问题。在 tinyioc 中解析它只是不断返回相同的实例而不是新实例。现在是代码

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);
    }
}

派生类目前是一个虚拟的,但在这里

public class HZone : HZoneBase
{
    public HZone(IHMetaDataStore store)
        : base(store)
    {
    }
}

现在因为这是一个外部库,所以我有一个面向类来访问 一切

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() 方法不断返回相同的实例。

测试代码

[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);
    }
}

我知道它可能是我在模式中缺少的一些简单的东西,但我不确定,如果有任何帮助,我们将不胜感激。

【问题讨论】:

    标签: dependency-injection tinyioc


    【解决方案1】:

    首先,请始终将代码简化为演示问题所绝对必要的内容,但要提供足够的代码以使其实际运行;我不得不猜测MemoryMetaDataStore 做了什么并自己实现它来运行代码。

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

    也就是说,container.Resolve&lt;HZoneBase&gt;() 将始终返回同一个实例,因为 TinyIoC 中的自动注册就是这样工作的 - 一旦解决了抽象,后续调用始终返回同一个实例。

    要更改此设置,请将以下行添加到 Hadrian 构造函数:

    this._container.Register<HZoneBase, HZone>().AsMultiInstance();
    

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

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

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

    【讨论】:

      【解决方案2】:

      在您的断言阶段,您不会增加cnt。您还使用实际值作为断言中的预期值。这会让人感到困惑,因为它说某些东西实际上是返回的实际值。

      断言部分应该是:

      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++;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-04
        相关资源
        最近更新 更多