如何将依赖性传递给城堡温莎型工厂

时间:2016-09-18 13:30:10

标签: c# castle-windsor factory

我正在使用Castle Windsor 3.3并拥有一个需要注入IMachine实例的ViewModel。这个数据直到运行时才可用,所以我正在尝试使用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使用我传递给工厂的物品?

由于

1 个答案:

答案 0 :(得分:0)

问题是使用TypedFactoryFacility Castle知道如何为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来协助Castle并解释解析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);
    
  3. 结果:(传递给容器/工厂的机器是IEquipmentData

    中的机器

    enter image description here