将Mediatr与Autofac集成

gro*_*kky 1 .net autofac .net-core mediatr

我正在使用.NET Core(注意:不是Web环境).我需要整合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();
Run Code Online (Sandbox Code Playgroud)

然后注册我的自定义东西:

  • 处理程序为瞬态的,即 InstancePerDependency()
  • 根据请求的前/后处理器,即 InstancePerLifetimeScope()
  • 行为是暂时的,即 InstancePerDependency()

例如

builder.RegisterType<EditCommandHandler>().AsImplementedInterfaces().InstancePerDependency();
Run Code Online (Sandbox Code Playgroud)

然而,大多数代码样本中我所看到的,特别是对于StructureMap,还有其他登记的负载(只是如IRequestHandler<,>,IRequestHandler<>,IAsyncRequestHandler<,>,IAsyncRequestHandler<>,ICancellableAsyncRequestHandler<,>,ICancellableAsyncRequestHandler<>,INotificationHandler<>,IAsyncNotificationHandler<>,ICancellableAsyncNotificationHandler<>),以及ASP.NET核心容器的整合是极其复杂了.我没有做过类似的事.

如果你有这个在生产中工作,你的配置与我的相比如何?谢谢!

Mic*_*iey 7

TL; DR;

我认为你的注册很好.


告诉我更多 - 也就是让我们逐一回答你的问题

您目前的注册

MediatR需要您注册SingleInstanceFactory,MultiInstanceFactory因为课程需要它们Mediator.

然后你需要注册你的处理程序和行为,这样你就没事了.

我可以做的一个评论是,看看你的例子,看起来你一个接一个地注册你的处理程序.虽然这是有效的 - 这是最重要的,但这意味着每次添加新的请求/处理程序对时,都必须在Autofac容器中注册处理程序.

我建议采用基于会议的注册方式,Autofac支持开箱即用.假设您的应用程序使用异步请求处理程序和异步通知处理程序,您可以编写如下内容:

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

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

关于所有处理程序类型

您担心没有MediatR公开的所有处理程序类型的注册.那很好.如果您不使用可取消的处理程序,则无需注册它们.您可以选择实现的处理程序类型.当您向MediatR发送请求时,它将使用提供的MultiInstanceFactory来确定您的处理程序是同步的,异步的还是可取消的异步.

另请注意,所有请求处理程序类型都有两种形式.只有一个泛型类型的IRequestHandler<TRequest>那些不返回值,而有两个泛型参数的那些IRequestHandler<TRequest, TResponse>返回值.但是,您的注册将取决于您是否使用它们.

ASP.NET核心集成部分

您使用Autofac,所以不要担心.该软件包旨在帮助您在使用ASP.NET Core DI容器时为您注册处理程序.它当然很复杂,因为它会进行程序集扫描以查找代码中的所有处理程序并为您注册它们.但是,再次,你不必担心,因为你使用另一个容器.


als*_*ami 5

对于找到这篇文章的任何人:我不久前创建了一个nuget-package作为 AutoFac 的扩展ContainerBuilder

我知道有一个基于 Microsofts-DI 的,但我的已经与 AutoFac 完全集成,并且也可以与ASP.NET-Core完美配合。

您需要做的就是在容器构建器上调用扩展方法并传入一个或多个程序集。

builder.AddMediatR(typeof(Startup).Assembly);
Run Code Online (Sandbox Code Playgroud)