次の例のように:
次のように MediatorModule クラスがあります。
public class MediatorModule : NinjectModule {
public class ContravariantBindingResolver : NinjectComponent, IBindingResolver {
public IEnumerable<IBinding> Resolve(Multimap<Type, IBinding> bindings, Type service) {
if (service.IsGenericType) {
var genericType = service.GetGenericTypeDefinition();
var genericArguments = genericType.GetGenericArguments();
if (1 == genericArguments.Count() && genericArguments.Single().GenericParameterAttributes.HasFlag(GenericParameterAttributes.Contravariant)) {
var argument = service.GetGenericArguments().Single();
var matches = bindings.Where(kvp => kvp.Key.IsGenericType
&& kvp.Key.GetGenericTypeDefinition().Equals(genericType)
&& kvp.Key.GetGenericArguments().Single() != argument
&& kvp.Key.GetGenericArguments().Single().IsAssignableFrom(argument))
.SelectMany(kvp => kvp.Value);
return matches;
}
}
return Enumerable.Empty<IBinding>();
}
}
public override void Load() {
Kernel.Components.Add<IBindingResolver, ContravariantBindingResolver>();
Kernel.Bind(services => services.FromAssemblyContaining<IMediator>().SelectAllClasses().BindDefaultInterface());
Kernel.Bind(services => services.FromThisAssembly().SelectAllClasses().InheritedFrom(typeof(IRequestHandler<,>)).BindAllInterfaces());
Kernel.Bind(services => services.FromThisAssembly().SelectAllClasses().InheritedFrom(typeof(INotificationHandler<>)).BindAllInterfaces());
Kernel.Bind(typeof(IPipelineBehavior<,>)).To(typeof(RequestPreProcessorBehavior<,>));
Kernel.Bind(typeof(IPipelineBehavior<,>)).To(typeof(RequestPostProcessorBehavior<,>));
Kernel.Bind(typeof(IPipelineBehavior<,>)).To(typeof(RequestExceptionActionProcessorBehavior<,>));
Kernel.Bind(typeof(IPipelineBehavior<,>)).To(typeof(RequestExceptionProcessorBehavior<,>));
Kernel.Bind<ServiceFactory>().ToMethod(ctx => t => ctx.Kernel.TryGet(t));
}
}
Quick Watch overservices.FromThisAssembly().SelectAllClasses().InheritedFrom(typeof(IRequestHandler<,>))
で、クラスが正しく検出されていることがわかります。
そして、これが私のコマンドとハンドラーの例です。
public class SupplierInvoice {
public class ProcessCommand : IRequest<ProcessedTransaction> {
public ProcessCommand(XmlDocument supplierInvoiceDocument)
=> SupplierInvoiceDocument = supplierInvoiceDocument;
public XmlDocument SupplierInvoiceDocument { get; }
}
public class ProcessCommandHandler : IRequestHandler<ProcessCommand, ProcessedTransaction> {
private readonly IXmlSerializer<SupplierInvoice> _serializer;
private readonly IValidator<SupplierInvoice> _validator;
private readonly IMediator _mediator;
public ProcessCommandHandler(IXmlSerializer<SupplierInvoice> serializer, IValidator<SupplierInvoice> validator, IMediator mediator) {
_serializer=serializer;
_validator=validator;
_mediator=mediator;
}
public async Task<ProcessedTransaction> Handle(ProcessCommand request, CancellationToken cancellationToken) {
if (request == null) return ProcessedTransaction.Succeeded;
var model = _serializer.Deserialize(request.SupplierInvoiceDocument.OuterXml);
var vr = _validator.Validate(model);
if (!vr.IsValid) // throwing exception with validation messages.
return await _mediator.Send(new CreateCommand(model));
}
}
}
BindAllInterfaces
メソッドを使用してハンドラーを登録しないようにするにはどうすればよいのでしょうか。
従来のバインディング構文を使用しても、リクエスト ハンドラは登録されません。
Kernel.Bind<IRequestHandler<SupplierInvoice.ProcessCommand, ProcessedTransaction>>().To<SupplierInvoice.ProcessCommandHandler>();
私は何が欠けていますか?