Cha*_*leh 3 .net castle-windsor inversion-of-control typed-factory-facility
我有以下类型的工厂:
public interface IWorkerFactory
{
IWorker Create(IJob job);
void Release(IWorker handler);
}
Run Code Online (Sandbox Code Playgroud)
这家工厂为特定工作创造了工人.所有工作都实现了,IJob但我想要一些处理不同类型工作的组件:
例如,这两者都来源于 IJob
interface IJobType1 : IJob { }
interface IJobType2 : IJob { }
Run Code Online (Sandbox Code Playgroud)
我想要两种工人类型,一种处理每种类型 IJob
class Worker1 : IWorker
{
public Worker1(IJobType1 job) { }
}
class Worker2 : IWorker
{
public Worker2(IJobType2 job) { }
}
Run Code Online (Sandbox Code Playgroud)
我已经试过这一点,但只是温莎拿起第一个实现的IWorker找到每一次,试图传递一个IJobType1到Worker2(反之亦然),它抛出一个异常
我已经查看了类型化的工厂组件选择器,但我无法弄清楚如何将其用于预期的效果
这是可能的,还是尝试为我的工人类使用通用接口更好?
编辑:
尝试使用通用接口但似乎没有给我我正在寻找的API ...关键问题是我真的不想知道它是什么类型IJob但我想要最合适的IWorker实例是在解决时创建.
我这样称呼它:
public void ProcessItem(IJob job)
{
IProcessingExceptionLog exLog = null;
IWorker worker = null;
try
{
worker = _workerFactory.Create(job);
// Attempt to process
worker.Process();
}
catch (Exception ex) .... etc
Run Code Online (Sandbox Code Playgroud)
即使我将作业转换为更加派生的界面,Windsor仍然会选择第一个IWorker ...它对检查方法的参数不感兴趣
理想情况下,我喜欢拦截或自定义解决过程的一些方法,以便我可以确定接受的最接近的匹配签名IJob是什么.
我可以尝试自己实现基于IWorkerFactory界面的混凝土工厂.它可以查看所有实现者IWorker并确定哪些构造函数与最接近的参数匹配,但是,如何解析此实例中的容器,因为我没有要使用的容器实例?我真的不喜欢让容器静止的想法
好吧我想出了这个 - 我想要两种类型,IWorker但我真的不想使用组件命名.我最终使用组件命名,但基于枚举,因为这已经是IJob我的一部分,我使用它作为我的组件选择器的一部分来确定使用哪个命名组件:
枚举:
public enum JobType
{
Type1,
Type2
}
Run Code Online (Sandbox Code Playgroud)
容器装置:
container.Register(Component.For<IWorker>()
.ImplementedBy<Worker1>()
.Named(JobType.Type1.ToString()));
container.Register(Component.For<IWorker>()
.ImplementedBy<Worker2>()
.Named(JobType.Type2.ToString()));
// And the factory:
container.Register(Component.For<IWorkerFactory>()
.AsFactory(x => x.SelectedWith<WorkerFactorySelector>()));
Run Code Online (Sandbox Code Playgroud)
然后IJob我实际上已经有了枚举:
public interface IJob
{
JobType JobType { get; }
}
Run Code Online (Sandbox Code Playgroud)
然后在WorkerFactorySelector:
public class WorkerFactorySelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(System.Reflection.MethodInfo method, object[] arguments)
{
var job = arguments[0] as IJob;
if (job != null)
return job.JobType.ToString();
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
这样我就不需要对任何常量进行操作,如果我需要新的工作类型,我可以将它们粘贴在枚举上,让工作根据它们的实现自动关联.
更新04/05/18:
正如Edu在评论中提到的那样,你还需要在容器中注册选择器,因为它将使用容器来解析选择器.