0

次の例のように:

MediatR.Examples.Ninject

次のように 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>();

私は何が欠けていますか?

4

1 に答える 1