Как пройти зависимость от замка Виндзор Типичный завод

Я использую Castle Windsor 3.3 и имею ViewModel, который нуждается в IMachineинъецированном экземпляре. Эти данные недоступны до выполнения, поэтому я пытаюсь использовать 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 использовать объект, который я передаю на завод?

благодаря

c#,castle-windsor,factory,

1

Ответов: 1


0

Проблема заключается в том, что использование TypedFactoryFacilityCastle знает, как разрешить для вас 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)

введите описание изображения здесь

C #, замок-Виндзорский, завод,
Похожие вопросы