如果您绝对必须调用该ICommandHandler<T>.Handle
方法并且您对系统的设计没有其他控制权,那么反射可能是您唯一的选择。没有很好的方法来处理从通用到非通用的转换。
否则,您可能有几个选择。
首先,如果你Dispatcher.Process
可以通用,你可以保存所有的铸件。
public static class Dispatcher
{
public static void Process<T>(T command) where T : ICommand
{
var handler = container.Resolve<ICommandHandler<T>>();
handler.Handle(command);
}
}
对于我在野外看到的此类问题,这是一个非常常见的解决方案。
如果你不能这样做,那么你可以让你的ICommandHandler<T>
接口实现一个非通用的ICommandHandler
基本接口。
public interface ICommandHandler
{
void Handle(ICommand command);
}
public interface ICommandHandler<T> : ICommandHandler
{
void Handle(T command);
}
在后一种情况下,您必须切换强类型命令处理程序实现以调用相同的内部逻辑进行通用或基本处理,否则您将根据调用获得不同的处理,这将是不好的:
public class SomeCommandHandler : ICommandHandler<SomeCommand>
{
public void Handle(ICommand command)
{
var castCommand = command as SomeCommand;
if(castCommand == null)
{
throw new NotSupportedException("Wrong command type.");
}
// Hand off to the strongly-typed version.
this.Handle(castCommand);
}
public void Handle(SomeCommand command)
{
// Here's the actual handling logic.
}
}
然后,当您解决强类型ICommandHandler<T>
转换时ICommandHandler
(如您的问题的示例代码所示)将起作用。
这也是一个非常常见的解决方案,但我在泛型可用之前存在的系统中看到了更多,其中正在添加更新的 API。
但是,在这里的所有情况下,问题实际上不在于 Autofac 正在返回一个对象。这是一个影响任何泛型到非泛型转换方案的类/类型设计问题。