你能解释一下大局吗? IComponents 或 IDependency 是如何使用的以及由谁使用?
我要求这样做的原因如下:
-
如果您事先知道 int 参数和所需 IDependency 之间的映射,并且它映射为单个 IDependency,那么我不会添加工厂,而是直接在安装程序中声明此依赖项:
container.Register(
Component.For<IDependency>()
.ImplementedBy<SomeDependency>()
.Named("SomeDependency"),
Component.For<IComponent>()
.ImplementedBy<MyComponent>()
.DependsOn(Dependency.OnComponent("dependency","SomeDependency")));
-
如果特定组件可能需要多个 IDependency 才能使用,因此我将更改 MyComponent 以依赖 IDependencyFactory 本身和 IDependency 以声明它回答哪个 int 参数。大致如下:
public interface IDependency
{
int Argument { get; set; }
}
public abstract class DependencyBase : IDependency
{
public DependencyBase(int argument) { Argument = argument; }
public int Argument { get; set; }
}
public class DependencyA : DependencyBase { public DependencyA() : base(1) {} }
public class DependencyB : DependencyBase { public DependencyB() : base(2) {} }
public interface IDependencyFactory
{
IDependency Create(int argument);
}
public interface IComponent { }
public class MyComponent : IComponent
{
public MyComponent(IDependencyFactory dependencyFactory)
{
DependencyFactory = dependencyFactory;
}
public IDependencyFactory DependencyFactory { get; set; }
}
public class Installer : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<IDependency>().ImplementedBy<DependencyA>(),
Component.For<IDependency>().ImplementedBy<DependencyB>(),
Component.For<IDependencyFactory>().AsFactory(),
Component.For<IComponent>().ImplementedBy<MyComponent>());
}
}
并且还实现了一个 ITypedFactoryComoponentSelector,它将通过参数 intager 从容器中解析。
基本上,如果您已经使用 AsFactory,我会说“为什么我需要实现工厂”(或 ITypedFactoryComoponentSelector)是正确的 - 但 TypedFactoryFacility 是开箱即用的映射形式在不同的对象类型之间返回不同的对象而不是不同的对象实例。也许阅读更多关于它的城堡文档。
希望对你有帮助
我已将 IComponent 和 IDependency 类更改为具有 DoSomething() 函数,以便我可以实际执行某些操作。
public interface IDependency
{
void DoSomething();
int Argument { get; set; }
}
public abstract class DependencyBase : IDependency
{
public DependencyBase(int argument) { Argument = argument; }
public void DoSomething() { }
public int Argument { get; set; }
}
现在 MyComponent 实现如下所示:
public class MyComponent : IComponent
{
public MyComponent(IDependencyFactory dependencyFactory)
{
DependencyFactory = dependencyFactory;
}
public void DoSomething(int argument)
{
var selectedDependency = DependencyFactory.Create(argument);
selectedDependency.DoSomething();
}
public IDependencyFactory DependencyFactory { get; set; }
}
我已经实现了一个 ITypedFactoryComponentSelector:
public class DependencyComponentSelector : ITypedFactoryComponentSelector
{
public DependencyComponentSelector(IKernel kernel)
{
Kernel = kernel;
}
public Func<IKernelInternal, IReleasePolicy, object> SelectComponent(MethodInfo method, Type type, object[] arguments)
{
return (k, r) =>
{
return from dependency in k.ResolveAll<IDependency>()
where dependency.Argument == int.Parse(arguments[0].ToString())
select dependency;
};
}
public IKernel Kernel { get; set; }
}
(显然应该添加输入验证以检查它是否已为正确的工厂方法调用)
然后在安装程序里把工厂的注册改成:
Component.For<DependencyComponentSelector>(),
Component.For<IDependencyFactory>().AsFactory(c=> c.SelectedWith<DependencyComponentSelector>()),