.net 将Mediatr与Autofac集成

cetgtptt  于 2023-03-24  发布在  .NET
关注(0)|答案(2)|浏览(209)

我正在使用.NET Core(注意:不是网络环境)。我需要集成MediatR和Autofac。
维基有一个指南和StructureMap示例。还有一个Autofac示例,我已经简化了。没有提到生命周期范围,但在一个单独的项目中,我找到了有用的注解并将其转换为Autofac。有很多代码示例,每个都是不同的。
目前为止我得到的是:

// enables contravariant Resolve() for interfaces with single contravariant ("in") arg
builder
  .RegisterSource(new ContravariantRegistrationSource());

// mediator itself
builder
  .RegisterType<Mediator>()
  .As<IMediator>()
  .InstancePerLifetimeScope();

// request handlers
builder
  .Register<SingleInstanceFactory>(context => {
    var ctx = context.Resolve<IComponentContext>();   // unsure why needed, but it works
    return t => { object o; return ctx.TryResolve(t, out o) ? o : null; };
  })
  .InstancePerLifetimeScope();

// notification handlers
builder
  .Register<MultiInstanceFactory>(context => {
    var ctx = context.Resolve<IComponentContext>();   // unsure why needed, but it works
    return t => (IEnumerable<object>)ctx.Resolve(typeof(IEnumerable<>).MakeGenericType(t));
  })
  .InstancePerLifetimeScope();

然后注册我的自定义内容:

  • 处理程序为 transient ,即InstancePerDependency()
  • 预处理器/后处理器,如InstancePerLifetimeScope()
  • transient 行为,即InstancePerDependency()

例如:

builder.RegisterType<EditCommandHandler>().AsImplementedInterfaces().InstancePerDependency();

然而,在我见过的大多数代码示例中,特别是对于StructureMap,有大量的其他注册(仅适用于例如IRequestHandler<,>IRequestHandler<>IAsyncRequestHandler<,>IAsyncRequestHandler<>ICancellableAsyncRequestHandler<,>ICancellableAsyncRequestHandler<>INotificationHandler<>IAsyncNotificationHandler<>ICancellableAsyncNotificationHandler<>),而ASP .NETCore容器的集成也是极其复杂的。我还没有做过类似的事情。
如果你有这个工作在生产,你的配置如何与我的比较?谢谢!

b4wnujal

b4wnujal1#

TL;DR;

我觉得你的注册没问题。
告诉我更多-又名让我们一个接一个地回答你的问题

您当前的注册数

MediatR需要您注册SingleInstanceFactoryMultiInstanceFactory,因为Mediator类需要它们。
然后,您需要注册处理程序和行为,您已经注册了,所以一切正常。
我可以做的一个评论是,从您的示例来看,看起来您 * 一个接一个地 * 注册处理程序。虽然这是有效的-这是最重要的,但这意味着每次添加新的请求/处理程序对时,都必须在Autofac容器中注册处理程序。
我建议改用基于约定的注册样式,Autofac支持开箱即用。假设您的应用程序使用异步请求处理程序和异步通知处理程序,您可以编写如下内容:

var openHandlersTypes = new[] { typeof(IAsyncRequestHandler<,>), typeof(IAsyncNotificationHandler<,>) };
foreach (var openHandlerType in openHandlersTypes)
{
    builder
        .RegisterAssemblyTypes(ThisAssembly)
        .AsClosedTypesOf(openHandlerType)
        .InstancePerDependency();
}

Autofac将扫描ThisAssembly并注册所有关闭openHandlersTypes中存在的开放泛型类型的类型。

关于所有句柄类型

你担心你没有注册MediatR公开的所有处理程序类型。这完全没有问题。如果你不使用可取消的处理程序,就不需要注册它们。你可以选择你实现的处理程序类型。当你向MediatR发送请求时,它会使用提供的MultiInstanceFactory来判断你的处理程序是同步的,异步的,或可取消的异步。
另外,请注意,所有请求处理程序类型都有两种类型。只有一个泛型类型(如IRequestHandler<TRequest>)的类型不返回值,而有两个泛型参数(如IRequestHandler<TRequest, TResponse>)的类型则返回值。但您的注册将取决于您是否使用它们。

ASP.NET Core集成块

你使用的是Autofac,所以不用担心它。如果你使用的是ASP.NET Core DI容器,这个包的目的是帮助你注册你的处理程序。它当然很复杂,因为它会进行程序集扫描,找到你代码中的所有处理程序,并为你注册它们。但是同样,你也不必担心,因为你使用的是另一个容器。

6ioyuze2

6ioyuze22#

任何人发现这篇文章:我创建了一个nuget-package作为AutoFac的ContainerBuilder的扩展。
我知道有一个基于Microsoft-DI的,但我的是完全集成了AutoFac和ASP .NET-Core以及完美的工作。
您所需要做的就是调用容器生成器上的扩展方法,并传入一个或多个程序集。

builder.AddMediatR(typeof(Startup).Assembly);

编辑2023-03-22

nuget-package的注册已更改,请查看README

相关问题