2016-09-18 6 views
1

Я использую Castle Windsor 3.3 и имею ViewModel, которому нужен экземпляр IMachine. Эти данные недоступны до выполнения, поэтому я пытаюсь использовать Typed Factory.Как передать зависимость от замка Windsor Typed Factory

public MachDataViewModel(IMachine mach) 
{ 
     _mach = machCfg; 
} 

public interface IEquipmentDataFactory 
{ 
    IEquipmentData Create(IMachine mach); 
    void Release(IMachine mach); 
} 

Вот мой регистрационный код:

container.AddFacility<TypedFactoryFacility>(); 
container.Register(
    Component.For<IWindsorContainer>().Instance(container), 
    Component.For<IEquipmentData>().ImplementedBy<EquipmentData>(), 
    Component.For<IMachine>().ImplementedBy<Machine>(), 
    Component.For<IEquipmentDataFactory>().AsFactory()); 

Когда я вызываю метод Create, он впрыскивает вновь экземпляра объекта, а не один я прохожу. Если я удалю запись Component.For<IMachine> в своей регистрации, это даст мне недостающую зависимость.

IEquipmentData ed = null; 
IMachine m = GetMachine(); 
ed = factory.Create(m); 

Как я могу заставить Windsor использовать объект, который я перехожу на завод?

Благодаря

ответ

0

Проблема заключается в том, что с помощью TypedFactoryFacility замок знает, как решить для вас IEquipmentData (потенциально), но когда он пытался решить ее зависимости он терпит неудачу, потому что они не зарегистрированы, и нет никакой другой SubResolver с знание того, как разрешить IMachine.

Используя следующие классы: (Те, в этом вопросе не компилировать)

public class IMachine 
{ 
    public Guid Id { get; set; } = Guid.NewGuid(); 
} 

public interface IEquipmentData { IMachine Machine { get; set; } } 
public class MachineDataViewModel : IEquipmentData 
{ 
    public IMachine Machine { get; set; } 
    public MachineDataViewModel(IMachine machine) { Machine = machine; } 
} 
  1. Вариант 1 - без TypedFactory:

    WindsorContainer container = new WindsorContainer(); 
    container.Register(
        Component.For<IEquipmentData>() 
          .ImplementedBy<MachineDataViewModel>() 
          .LifestyleTransient()); 
    
    var machine = new IMachine(); 
    var resultWithoutFactory = container.Resolve<IEquipmentData>(new Dictionary<string, object> { ["machine"] = machine }); 
    
  2. Вариант 2 - с TypedFactoryFacility. В этом случае вам нужно будет ввести ITypedFactoryComponentSelector, чтобы помочь замку, и объясните, какие аргументы для разрешения IEquipmentData есть с IMachine, который вы передаете.

    public interface IMachineFactory 
    { 
        IEquipmentData Create(IMachine machine); 
    } 
    
    public class EquipmentDataComponentSelector : ITypedFactoryComponentSelector 
    { 
        public Func<IKernelInternal, IReleasePolicy, object> SelectComponent(MethodInfo method, Type type, object[] arguments) 
        { 
         return (k, s) => k.Resolve<IEquipmentData>(new Dictionary<string, object> { ["machine"] = arguments[0] }); 
        } 
    } 
    

    Главная:

    WindsorContainer container = new WindsorContainer(); 
    container.AddFacility<TypedFactoryFacility>(); 
    container.Register(
        Component.For<IEquipmentData>() 
          .ImplementedBy<MachineDataViewModel>() 
          .LifestyleTransient(), 
        Component.For<EquipmentDataComponentSelector>(), 
        Component.For<IMachineFactory>() 
          .AsFactory(f => f.SelectedWith<EquipmentDataComponentSelector>())); 
    
    var machine = new IMachine(); 
    var factory = container.Resolve<IMachineFactory>(); 
    var resultWithFactory = factory.Create(machine); 
    

Результат: (машина передается в контейнер/завод является один в IEquipmentData)

enter image description here

+0

@cajundave - Помогла ли эта помощь вам решить вопрос? –