2016-06-13 5 views
4

Я ожидал, что следующее будет производить два отдельных экземпляра при использовании typed factory facility.Почему заводская фабрика Castle Windsor возвращает тот же экземпляр при создании с разными параметрами

using System; 
using Castle.Facilities.TypedFactory; 
using Castle.MicroKernel.Registration; 
using Castle.Windsor; 

namespace ConsoleApplication 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var container = new WindsorContainer(); 

      container.AddFacility<TypedFactoryFacility>(); 

      container.Register(Component 
       .For<IFactory>() 
       .AsFactory() 
       .LifestyleSingleton()); 

      container.Register(Component 
       .For<IImplementation>() 
       .ImplementedBy<Implementation>() 
       .LifestylePerThread()); 

      var factory = container.Resolve<IFactory>(); 
      var implementation1 = factory.Create(1); 
      var implementation2 = factory.Create(2); 

      Console.WriteLine(implementation1 == implementation2);//Returns true! 
      Console.Read(); 
     } 
    } 

    public interface IFactory 
    { 
     IImplementation Create(int dependency); 
    } 

    public interface IImplementation 
    {} 

    public class Implementation : IImplementation 
    { 
     private readonly int _dependency; 

     public Implementation(int dependency) 
     { 
      _dependency = dependency; 
     } 
    } 
} 

Я также пробовал с параметром в качестве ссылочного типа, который переопределяет .Equals() и .GetHashCode() вместо с междунар, но это не имеет никакого значения.

Я понимаю, что я могу использовать LifestyleTransient для решения этой проблемы, но на самом деле хочу получить тот же экземпляр, если я передам тот же параметр.

+0

Помогло найти местонахождение AsFactory. +1 для включения пространств имен в код. – w0051977

ответ

3

Ваших ожидания неверны.

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

Ваш второй запрос выполнен из того же потока и предназначен для той же службы, что и Windsor правильно возвращает тот, который уже был сконструирован.

В то время как предложение Гилада является возможным для вас, вы все равно можете «сразиться» с контейнером и сделать вещи более сложными, чем они должны быть.

Я предлагаю вам использовать механизмы, доступные в Виндзоре, которые полностью полагаются на типы услуг (интерфейсы) для дифференциации сервисов друг от друга.

Спросите себя, что это касается двух экземпляров, которые отличаются друг от друга и отражают эти различия в терминах интерфейсов. например возможно, у вас должны быть IBigImplementation и ISmallImplementation? Затем реализации этих различных сервисов можно зарегистрировать и сконфигурировать в контейнере; вы получаете все пулы/повторное использование; и потребительский код остается блаженно не осознанным и отделенным от деталей реализации.

[RANT: Несмотря на то, что заводы обеспечивают большую гибкость, я обычно рассматриваю использование параметров для заводских методов как запах кода. Как вы обнаружили, это требует от потребителя сделать предположения о жизненном цикле реализации службы. Это также означает, что рычаги и переключатели, которые управляют деталями реализации, разбросаны по базе кода, а не координируются централизованно в регистре регистрации контейнера.]

2

Из того, что я знаю о Castle TypedFactoryFacility, вы попробуете и разрешите для вас тип в соответствии с интерфейсом фабрики. Если у вас есть функция вроде IImplementation Create(int dependency), тогда она попытается решить из Ядра объект типа IImplementation. Вот почему вы получаете то же самое, когда вы зарегистрированы в Singelton.

То, что вы на самом деле ищете, похоже на «TypedFactory», которое вернет экземпляр не по типу, а по экземпляру объекта, который у вас есть. Что вы можете сделать, так это реализовать ITypedFactoryComponentSelector, который попытается решить из kernel и IImplementation, который также передал вам int dependency, и если один из них не существует, зарегистрируйте его перед его возвратом.

Вы можете посмотреть здесь для более глубокого проникновения в суть на TypedFactory и реализаций собственного ITypedFactoryComponentSelector: https://github.com/castleproject/Windsor/blob/master/docs/typed-factory-facility-interface-based.md

Надеется, что это помогает

 Смежные вопросы

  • Нет связанных вопросов^_^