我正在使用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使用我传递给工厂的物品?
由于
答案 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 - 没有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 - 使用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);
结果:(传递给容器/工厂的机器是IEquipmentData
)