繁体   English   中英

结构图,使用默认实例和命名实例时的异常行为

[英]Structuremap, odd behavior when using default instance and named instance Options

有人能够解释以下行为吗?

特别是为什么当TestUseAndAdd没有出现时,为什么TestInitializeAndConfigure_Fails失败...以及为什么当TestUseOrderChanged没有出现时,为什么TestUse_Fails失败。

谢谢

interface IResource {}
class TheFirstResource : IResource {}
class TheSecondResource : IResource {}

[TestFixture]
class Test
{
    [Test]
    public void TestUse_Fails()
    {
        ObjectFactory.Initialize(init =>
        {
            init.For<IResource>().Singleton().Use<TheFirstResource>();
            init.For<IResource>().Singleton().Use<TheSecondResource>().Named("test");
        });

        IResource r1 = ObjectFactory.GetInstance<IResource>();
        IResource r2 = ObjectFactory.GetNamedInstance<IResource>("test");

        Console.WriteLine(string.Format("TestUse_Fails \n{0}\n{1}", r1, r2));
    }

    [Test]
    public void TestUseOrderChanged()
    {
        ObjectFactory.Initialize(init =>
        {
            init.For<IResource>().Singleton().Use<TheSecondResource>().Named("test");
            init.For<IResource>().Singleton().Use<TheFirstResource>();
        });

        IResource r1 = ObjectFactory.GetInstance<IResource>();
        IResource r2 = ObjectFactory.GetNamedInstance<IResource>("test");

        Console.WriteLine(string.Format("TestUseOrderChanged \n{0}\n{1}", r1, r2));
    }

    [Test]
    public void TestUseAndAdd()
    {
        ObjectFactory.Initialize(init =>
        {
            init.For<IResource>().Singleton().Use<TheFirstResource>();
            init.For<IResource>().Singleton().Add<TheSecondResource>().Named("test");
        });

        IResource r1 = ObjectFactory.GetInstance<IResource>();
        IResource r2 = ObjectFactory.GetNamedInstance<IResource>("test");

        Console.WriteLine(string.Format("TestUseAndAdd \n{0}\n{1}", r1, r2));
    }

    [Test]
    public void TestInitializeAndConfigure_Fails()
    {
        ObjectFactory.Initialize(init =>
        {
            init.For<IResource>().Singleton().Use<TheFirstResource>();
        });

        ObjectFactory.Configure(init =>
        {
            init.For<IResource>().Singleton().Add<TheSecondResource>().Named("test");
        });

        IResource r1 = ObjectFactory.GetInstance<IResource>();
        IResource r2 = ObjectFactory.GetNamedInstance<IResource>("test");

        Console.WriteLine(string.Format("TestInitializeAndConfigure_Fails \n{0}\n{1}", r1, r2));
    }
}

产量

TestUse_Fails 
Smtesting.TheSecondResource 
Smtesting.TheSecondResource 

TestUseOrderChanged 
Smtesting.TheFirstResource 
Smtesting.TheSecondResource 

TestInitializeAndConfigure_Fails 
Smtesting.TheSecondResource 
Smtesting.TheSecondResource 

TestUseAndAdd 
Smtesting.TheFirstResource 
Smtesting.TheSecondResource 

只是为了帮助那些会偶然发现这个问题的人,这是杰米(Jermey)先生本人的回答。 他在这里的博客上回答了这个问题。


For()。Use()具有破坏性。 一次执行For()。Use()以获取默认值,第二次调用For()。Add()以获取第二次注册。 查看这2个API调用的Xml注释。


TestUse_Fails对我来说很有意义,因为调用Use <>()本质上意味着您正在为该类型指定默认实例(并将其添加)。 一般情况下,最后一个胜出-我找不到明确的文档,但这是大多数容器工作的方式。 r1调用获取TheSecondResource(最后一个设置为默认值),r2调用获取命名的资源。

TestUseOrderChanged之所以起作用,是因为init / config之后的默认值是TheFirstResource,但是TheSecondResource仍使用名称添加到了容器中。 因此,r1获取TheFirstResource(因为它是最后一个,因此是默认值),而r2正确获取TheSecondResource作为命名实例。

TestInitializeAndConfigure_Fails是奇数。 从我坐的地方,r1应该获得TheFirstResource,因为默认值尚未被覆盖-Use <>()没有被再次调用。 调用初始化后调用配置应该根据文档重置容器。 我会尝试调用ObjectFactory.WhatDoIHave()并查看在Initialize()和Configure()调用之后是否还注册了TheFirstResource。

对我来说,这似乎是一个错误,我会考虑将其提交给structuremap用户组(http://groups.google.com/group/structuremap-users)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM