我正在尝试使用Castle Windsor解决带有约束的混合开放/关闭泛型类型。如果Foo实现了IFoo<>,则应该能够解决任何开放式泛型:
container.Register(Component.For(typeof(IFoo<>).ImplementedBy(typeof(Foo<>)));
我的情况略微复杂:
我有以下Handler
类:
public abstract class CommandHandlerBase<TCommand, TResponse>
: IRequestHandler<TCommand, TResponse>
where TCommand : IRequest<TResponse>
{
public abstract Task<TResponse> Handle(
TCommand request, CancellationToken cancellationToken);
}
public class AddMasterDataEntityCommandHandler<TNewEntityData>
: IRequestHandler<TNewEntityData, Response>
where TNewEntityData : IRequest<Response>
{
public Task<Response> Handle(
TNewEntityData request, CancellationToken cancellationToken)
{
// ...
}
}
这里的想法是
AddMasterDataEntityCommandHandler
将成为一个通用命令处理程序,可以处理任何类型为 TNewEntityData
的合同。
由于我正在使用 Mediatr,因此我的合约必须实现 IRequest<,>
。 在这种情况下,我强制所有处理程序都应返回一个 Response
。示例用法:
Response response = await mediator.Send(new AddMasterDataEntityCommand<NewPlace>());
public static void Main(string[] args)
{
var container = new WindsorContainer();
container.Register(Types.FromThisAssembly()
.BasedOn(typeof(IRequestHandler<,>))
.Unless(t => t.IsAbstract || t.IsInterface)
.WithServices(typeof(IRequestHandler<,>))
.LifestyleTransient());
var instance = container.Resolve(typeof(IRequestHandler<NewData, Response>));
}
然而,测试抛出了一个异常,指示我的代码存在错误:
Castle.MicroKernel.Handlers.GenericHandlerTypeMismatchException:“类型ConsoleApp4.NewData,ConsoleApp4.Response不满足组件'ConsoleApp4.AddMasterDataEntityCommandHandler'1'的实现类型ConsoleApp4.AddMasterDataEntityCommandHandler'1'的泛型约束。这很可能是你代码中的一个错误。”
我看不到问题在哪里,CW应该能够解决开放/封闭泛型,对吧?此外,问题似乎与附加的Response参数作为
TResponse
类型有关。我注册组件的方式有问题吗?我相信我没有搞砸泛型约束...
提前感谢任何人能够查看。
NewData
没有实现IRequest<Response>
。 - Phil Degenhardtnew AddMasterDataEntityCommandHandler<NewData>()
时,它是否有效? - Krzysztof KozmicNewData
实现了IRequest<Response>
。 - rumblefx0IGenericImplementationMatchingStrategy
可能会有所帮助。例如,请参见此链接:http://kozmic.net/2013/07/24/on-castle-windsor-and-open-generic-component-arity/ - Krzysztof Kozmic