使用 MediatR 和 Autofac 的组件注册问题

我正在使用 Autofac 和 MediatR 构建基于 CQRS 的 .Net Core 2.1 应用程序。


public class MediatorModule : Autofac.Module

{

    protected override void Load(ContainerBuilder builder)

    {

        builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces();


        var mediatrOpenTypes = new[]

        {

            typeof(IRequestHandler<,>),

            typeof(INotificationHandler<>),

        };


        foreach (var mediatrOpenType in mediatrOpenTypes)

        {

            builder

                .RegisterAssemblyTypes(typeof(CreateMessageCommand.GetTypeInfo().Assembly)

                .AsClosedTypesOf(mediatrOpenType)

                .AsImplementedInterfaces();

        }


        builder.RegisterGeneric(typeof(RequestPostProcessorBehavior<,>)).As(typeof(IPipelineBehavior<,>));

        builder.RegisterGeneric(typeof(RequestPreProcessorBehavior<,>)).As(typeof(IPipelineBehavior<,>));


        builder.Register<ServiceFactory>(ctx =>

        {

            var c = ctx.Resolve<IComponentContext>();

            return t => c.Resolve(t);

        });


    }

}

当我将命令提供给中介时,它工作得很好,并且命令处理程序上的 Handle() 被执行。


var cmd = new CreateMessageCommand("Foo")

_mediator.Send(cmd)

当我以这种方式执行时,事情并不顺利


var cmd = new CreateMessageCommand("Foo")

var req = new IdentifiedCommand<CreateMessageCommand, bool>(cmd, @event.Id);

await _mediator.Send(req);



尚方宝剑之说
浏览 399回答 2
2回答

绝地无双

您发送给 MediatR 的命令类型为IdentifiedCommand<CreateMessageCommand, bool>。因此 MediatR 将寻找类型为 的处理程序IRequestHandler<IdentifiedCommand<CreateMessageCommand, bool>, bool>>。DI 容器通常会首先寻找完全匹配的对象,然后考虑开放的泛型类型注册。在这种情况下,它将查找IRequestHandler<,>注册,并为其插入类型参数IdentifiedCommand<CreateMessageCommand, bool>、 和bool。但是,您的命令处理程序没有实现IRequestHandler<T, R>,而是实现了IRequestHandler<IdentifiedCommand<T, R>, R>不适合于此的。因此 DI 容器没有找到处理程序并且会引发该错误。为了使其工作,您必须以 DI 容器查找它的方式实现该类型。所以你将不得不实施IRequestHandler<T, R>。不幸的是,这也意味着您无法使用类型安全的方式IdentifiedCommand<T, R>在处理程序中接受。相反,您只会收到一个T您必须处理的请求。

狐的传说

添加这个解决了我的问题。builder.RegisterType(typeof(IdentifiedCommandHandler<CreateMessageCommand, bool>))&nbsp; &nbsp; .As<IRequestHandler<IdentifiedCommand<CreateMessageCommand, bool>, bool>>()&nbsp; &nbsp; .AsImplementedInterfaces();
打开App,查看更多内容
随时随地看视频慕课网APP