3

我正在使用 .NET Core(注意:不是 Web 环境)。我需要集成 MediatR 和 Autofac。

wiki 有一个指南和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();

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

  • 处理程序作为瞬态,即InstancePerDependency()
  • 预处理器/后处理器按请求,即InstancePerLifetimeScope()
  • 行为是短暂的,即InstancePerDependency()

例如

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

然而,在我见过的大多数代码示例中,尤其是对于 StructureMap,还有大量其他注册(仅用于例如IRequestHandler<,>IRequestHandler<>IAsyncRequestHandler<,>IAsyncRequestHandler<>ICancellableAsyncRequestHandler<,>ICancellableAsyncRequestHandler<>INotificationHandler<>IAsyncNotificationHandler<>ICancellableAsyncNotificationHandler<>),而且ASP.NET Core 容器的集成也非常复杂。我没有做过类似的事情。

如果您在生产中使用此功能,那么您的配置与我的配置相比如何?谢谢!

4

2 回答 2

9

TL;博士;

我认为你的注册很好。


告诉我更多信息 - 也就是让我们一一回答您的问题

您当前的注册

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 容器,该包旨在帮助您为您注册处理程序。这当然很复杂,因为它会进行汇编扫描以查找代码中的所有处理程序并为您注册它们。但同样,您无需担心,因为您使用的是另一个容器。

于 2017-03-16T21:33:04.870 回答
5

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

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

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

builder.AddMediatR(typeof(Startup).Assembly);
于 2018-12-11T08:09:38.410 回答