具有 ASP.NET 核心 DI 的 MediatR

MediatR with ASP.NET Core DI

我正在试用新的 ASP.NET 核心,目前正在创建一个 API,我想从 JavaScript 前端调用它。

我想使用调解器模式来减少耦合,我找到了 Jimmy Bogard 的库MediatR

我的问题在于使用 DI 中的构建将其连接起来,我尝试查看 examples,但无法破解它如何绑定到启动时的 ConfigureServices 方法 class.

有没有人有任何见解?

更新:我通过我的 ConfigureService 方法让它工作了:

services.AddScoped<SingleInstanceFactory>(p => t => p.GetRequiredService(t));

services.Scan(scan => scan
        .FromAssembliesOf(typeof(IMediator), typeof(MyHandler.Handler))
        .AddClasses()
        .AsImplementedInterfaces());

我成功了,我的代码:

public void ConfigureServices(IServiceCollection services)
{
      services.AddScoped<SingleInstanceFactory>(p => t => p.GetRequiredService(t));
      services.AddScoped<MultiInstanceFactory>(p => t => p.GetRequiredServices(t));
      services.Scan(scan => scan
              .FromAssembliesOf(typeof(IMediator), typeof(MyHandlerOne.Handler))
              .FromAssembliesOf(typeof(IMediator), typeof(MyHandlerTwo.Handler))
             .AddClasses()
             .AsImplementedInterfaces());
}

我有一个 class 实现了 MultiInstanceFactory 需要的 GetRequiredService:

public static class GetServices
{
    public static IEnumerable<object> GetRequiredServices(this IServiceProvider provider, Type serviceType)
    {
        return (IEnumerable<object>)provider.GetRequiredService(typeof(IEnumerable<>).MakeGenericType(serviceType));
    }
}

我创建了一个 DI helper for ASP.NET Core RC2,您可以将其添加到您的启动程序中。它为您提供了基于基本约定的映射,因此如果您有 class,例如:

MyClass : IMyClass

它将 IMyClass 映射到 IOC 容器中,这将使其可用于注入。

我还添加了 MediatR 的映射。

要使用它只需将 class 添加到您的项目中,然后在您的 startup.cs class 中将您需要的行添加到 ConfigureServices() 方法中:

public void ConfigureServices(IServiceCollection services)
{
    //Other Code here......

    var ioc = new PearIoc(services);

    //ioc.AddTransient<IEmailSender, AuthMessageSender>();
    //ioc.AddTransient<ISmsSender, AuthMessageSender>();

    ioc.WithStandardConvention();
    ioc.WithMediatR();
    ioc.RunConfigurations();
}

我添加 AddTransient() 方法只是为了方便(您也可以只使用 services.AddTransient()),但它也会公开 IServiceCollection 以防您需要使用它做更多事情。

您也可以像我对 .WithMediatR() 扩展所做的那样扩展它并编写您自己的自定义映射。

截至 2016 年 7 月,MediatR 的作者 Jimmy Bogard 发布了一个包来注册 MediatR 和 Handlers,使用 ASP.Net Core DI 服务(实际上是接口 IServiceCollection,在 Microsoft.Extensions.DependencyInjection 中实现并且不限于仅在 ASP.Net 核心中使用)。

MediatR.Extensions.Microsoft.DependencyInjection

Link to GitHub Project.

Link to NuGet Package information.

可以找到介绍该软件包及其功能的博客 post here

直接从(很短的)博客中复制的示例注册post:

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc();

  services.AddMediatR(typeof(Startup));
}

此包执行多项功能以启用 MediatR,包括所需的处理程序程序集扫描:

You can either pass in the assemblies where your handlers are, or you can pass in Type objects from assemblies where those handlers reside. The extension will add the IMediator interface to your services, all handlers, and the correct delegate factories to load up handlers. Then in your controller, you can just use an IMediator dependency:

public class HomeController : Controller
{
  private readonly IMediator _mediator;

  public HomeController(IMediator mediator)
  {
    _mediator = mediator;
  }
  public IActionResult Index()
  {
    var pong = _mediator.Send(new Ping {Value = "Ping"});
    return View(pong);
  }
}

https://dotnetcoretutorials.com/ 有一个很好的教程。这是正确安装和配置 MediatR 的示例代码。

正在安装 MediatR

我们需要做的第一件事是安装 MediatR nuget 包。所以从你的包管理器控制台 运行 :

安装包 MediatR

我们还需要安装一个包,允许我们使用 .NET Core 中的内置 IOC 容器来发挥我们的优势(我们很快就会看到更多)。所以还要安装以下软件包:

安装包MediatR.Extensions.Microsoft.DependencyInjection

最后我们打开 startup.cs 文件。在我们的 ConfigureServices 方法中,我们需要添加一个调用来注册所有 MediatR 的依赖项。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMediatR(Assembly.GetExecutingAssembly());
    //Other injected services. 
}

这是link:https://dotnetcoretutorials.com/2019/04/30/the-mediator-pattern-part-3-mediatr-library/

希望对您有所帮助。

根据 MediatR 文档注册 MediatR 服务和所有处理程序,您应该以这种方式使用 AddMediatR 方法:

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc();

  services.AddMediatR(typeof(Startup));
}

这很简单,也很舒服,但是如果您想更换其中一个处理器怎么办? 然后你应该找到 oldhandler.cs 并从中删除接口,这样 ID 就不会与多个实现发生冲突。

为避免这种情况,我的建议是手动

注册每个处理程序
     public void ConfigureServices(IServiceCollection services)
    {
      services.AddMvc();
    
      services.AddMediatR(typeof(Mediator)); //registering MediatR and all required dependencies
      //registering handlers
      services.AddScoped<IRequestHandler<CreateProductCommand, int>,CreateProductCommandHandler>(); 
      services.AddScoped<IRequestHandler<DeleteProductCommand, int>,DeleteProductCommandHandler>();     

    }

此解决方案允许您为同一个命令实现多个处理程序,并控制 使用的实现