将Mediatr与Autofac集成

时间:2017-03-16 15:06:42

标签: .net .net-core autofac mediatr

我使用的是.NET Core(注意:不是网络环境)。我需要集成Mediatr和Autofac。

wiki has a guide和StructureMap示例。还是Autofac sample,我已经简化了。没有提及生命周期范围,但在a separate project中,我找到了有用的注释并将它们转换为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();

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

  • 处理程序为瞬态,即InstancePerDependency()
  • 根据请求预处理器/后处理器,即InstancePerLifetimeScope()
  • 行为为瞬态,即InstancePerDependency()

例如

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

然而,在我见过的大多数代码示例中,特别是对于StructureMap,还有大量其他注册(仅适用于IRequestHandler<,>IRequestHandler<>IAsyncRequestHandler<,>,{{1 }},IAsyncRequestHandler<>ICancellableAsyncRequestHandler<,>ICancellableAsyncRequestHandler<>INotificationHandler<>IAsyncNotificationHandler<>),ASP.NET Core container's整合也非常复杂。我没有做过类似的事情。

如果你有正在投入生产,你的配置与我的相比如何?谢谢!

2 个答案:

答案 0 :(得分:7)

TL; DR;

我认为你的注册很好。

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

您当前的注册

MediatR需要您注册SingleInstanceFactory课程所需的MultiInstanceFactoryMediator

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

我可以做的一个评论是,看看你的例子,看起来你一个接一个地注册你的处理程序 。虽然这是有效的 - 这是最重要的,但这意味着每次添加新的请求/处理程序对时,都必须在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来确定您的处理程序是同步的,异步的还是可取消的异步。

另外,请注意所有请求处理程序类型都有两种形式。仅one generic type like IRequestHandler<TRequest>的值不返回值,而two generic parameters like IRequestHandler<TRequest, TResponse>的值返回值。但是,您的注册将取决于您是否使用它们。

ASP.NET核心集成部分

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

答案 1 :(得分:4)

对于任何发现此帖子的人:不久前,我创建了nuget-package作为AutoFac ContainerBuilder的扩展。

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

您需要做的就是在container-builder上调用extension方法并传入一个或多个程序集。

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