Структура карты, странное поведение при использовании экземпляра по умолчанию и именованного экземпляра - PullRequest
1 голос
/ 21 сентября 2011

Кто-нибудь может объяснить следующее поведение?

Особенно, почему 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 

Ответы [ 2 ]

2 голосов
/ 22 января 2012

Просто чтобы помочь людям, которые наткнутся на это, вот ответ от самого человека Джерми.Он ответил на вопрос в своем блоге здесь .


For (). Использование () разрушительно.Сделайте For (). Используйте () один раз, чтобы получить значение по умолчанию, и второй вызов For (). Add (), чтобы получить 2-ую регистрацию.Посмотрите на комментарии XML для этих двух вызовов API.


1 голос
/ 21 сентября 2011

TestUse_Fails имеет смысл для меня, потому что вызов Use <> () по сути означает, что вы указываете экземпляр по умолчанию для типа (и добавляете его). Последний в общем выигрывает - я не могу найти явные документы по этому вопросу, но так работают большинство контейнеров. Вызов r1 получает TheSecondResource (последний установлен по умолчанию), а вызов r2 получает именованный ресурс.

TestUseOrderChanged работает, потому что по умолчанию после init / config используется TheFirstResource, но TheSecondResource все еще добавлен в контейнер с именем. Таким образом, r1 получает TheFirstResource (как он был последним и, следовательно, по умолчанию), а r2 правильно получает TheSecondResource в качестве именованного экземпляра.

TestInitializeAndConfigure_Fails является нечетным. Оттуда, где я сижу, r1 должен получить TheFirstResource, так как значение по умолчанию не было перезаписано - Use <> () больше не вызывалось. Вызов Configure после вызова Initialize должен , а не сбросить контейнер в соответствии с документами. Я бы попытался вызвать ObjectFactory.WhatDoIHave () и посмотреть, зарегистрирован ли TheFirstResource даже после вызовов Initialize () и Configure ().

Для меня это выглядит как ошибка, и я бы посоветовал отправить ее в группу пользователей Structuremap (http://groups.google.com/group/structuremap-users).

...