繁体   English   中英

如何在Castle Windsor容器中解析与对象匹配的泛型类型

[英]How to resolve a generic type in a Castle Windsor container that matches an object

我有以下接口和类。

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容器中注册。 收到命令后,我想在可以处理命令的容器中找到处理程序。

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<>))

我不知道哪个处理程序可以处理我的命令。

最好的选择是使用反射:

dynamic handler = container.Resolve(
    typeof(IHandler<>).MakeGenericType(cmd.GetType()));
handler.Handle(cmd);

但是真正的答案是重构您的代码,您正在与类型系统作斗争。 温莎在这里无济于事,它可以使您引用适当的类型,但在调用Handle(cmd)时仍必须IHandler<T>为适当的IHandler<T> 拥有通用方法会更好:

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的各种解决方案还有很多问题-您可能需要在此处进行一些研发。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM