1

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

特别是为什么 TestInitializeAndConfigure_Fails 在 TestUseAndAdd 没有失败时失败......以及为什么 TestUse_Fails 在 TestUseOrderChanged 没有失败时失败。

谢谢

代码

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 
4

2 回答 2

2

只是为了帮助那些偶然发现这一点的人,这里是杰米本人的回答。他在他的博客上回答了这个问题


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


于 2012-01-22T17:53:43.283 回答
1

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

TestUseOrderChanged 有效,因为 init/config 之后的默认值是 TheFirstResource,但 TheSecondResource 仍然已添加到具有名称的容器中。所以 r1 获得 TheFirstResource (因为它是最后一个,因此是默认值),并且 r2 正确地获得 TheSecondResource 作为命名实例。

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

对我来说,这看起来像一个错误,我会考虑将其提交给结构映射用​​户组 (http://groups.google.com/group/structuremap-users)。

于 2011-09-21T19:36:16.460 回答