我有以下接口和类。
interface ICommand { ... }
class Command1 : ICommand { ... }
class Command1 : ICommand { ... }
interface IHandle<TCommand> where TCommand : ICommand
{
IResult Handle(TCommand command);
}
Command1Handler : IHandle<Command1> { ... }
Command2Handler : IHandle<Command2> { ... }
Command1Handler和Command2Handler在Castle Widsor容器中注册。当我收到命令时,我想在容器中找到可以处理命令的Handler。
public IResult ProcessCommand(ICommand command)
{
var handler = Container.Resolve //How to resolve based on command?
return handler.Handle(command);
}
我不能打电话
Container.Resolve<IHandle<Command1>>()
因为我不知道TCommand,如果我知道
Container.ResolveAll(typeof(IHandle<>))
我不知道哪个处理程序可以处理我的命令。
答案 0 :(得分:0)
最好的选择是使用反射:
dynamic handler = container.Resolve(
typeof(IHandler<>).MakeGenericType(cmd.GetType()));
handler.Handle(cmd);
但真正的答案是重构你的代码,你正在与类型系统作斗争。温莎在这里没有帮助,它可以让你引用正确的类型,但是当你打电话给IHandler<T>
时,你仍然必须投射到正确的Handle(cmd)
。使用通用方法会好得多:
void Handle<T>(ICommand<T> cmd) {
var handler = container.Resolve<IHandler<T>>();
handler.Handle(cmd);
}
interface ICommand<T> { }
class Command1 : ICommand<Command1> { }
或使用多态的魔力:
class BaseCommand<T> : ICommand<T> {
public void FindAndExecuteHandler(IKernel kernel) {
kernel.Resolve<IHandler<T>>().Handle(this);
}
}
class Command1 : BaseCommand<Command1> { }
cmd1.FindAndExecuteHandler(container);
与你的问题非常相似的是找到给定模型的IValidator<T>
,有很多关于SO的问题和各种解决方案 - 你可能想在这里做一些R&amp; D.