【翻译】asp.net core中使用MediatR

这篇文章来自:https://ardalis.com/using-mediatr-in-aspnet-core-appsjson

本文做为翻译,有一些单词翻译成中文可能会有一些误解(对于读者)或者错误(对于做者)的地方,因此在文章中你能够看到一些单词没有进行翻译。若是有不对的地方,请指出,谢谢。浏览器

在Asp.net core中使用MediatR

我已经开始考虑使用MediatR做为个人领域事件实现。为了达到这个目的,我用asp.net core建立了一个示例程序,总的来讲是很是容易的,若是你以前没有使用过MediatR,或者你正在找一个使用它的示例程序,那么就继续阅读吧。app

安装MediatR

假设你使用的是Visual studio,你能够经过nuget的ui来安装下面这两个包:asp.net

不是用visual studio的话本身找办法安装吧。async

在Startup类中配置MediatR

下一步,在Startup类中,在ConfigureServices方法中添加以下代码:微服务

services.AddMediatR();

// if you have handlers/events in other assemblies
// services.AddMediatR(typeof(SomeHandler).Assembly, 
//                     typeof(SomeOtherHandler).Assembly);

在个人示例项目中由于我只有一个工程/程序集,因此没有必要添加其余的。若是你有不仅一个程序集须要被配置MediatR,那么你能够按照上面代码中注释掉的那样来配置。ui

注意:起初我用了Steve Gordon’s helpful article to register my types这个指引,可是MediatR.Extensions.Microsoft.DependencyInjection 包获得了更好的支持和更健壮的成长(更别说更少的代码)。我建议使用这个包。this

MediatR 实战

固然,若是你想要确认MediatR在你的asp.net core项目中运做,最高的办法是建立一些简单的类型并验证是否能达到预期的效果。MediatR支持两种消息类型:Request/Response和Notification。我使用它的大多数状况是Notification这种模式。由于我但愿用它来作模型的领域事件(若是你对于领域事件不熟悉的话,先了解一下它再回来)。要想使用notifications所指望获得的行为,你须要定义一些实现了INotification的类型,和一些实现了INotificationHandler<sometype>的handler。当你要发布一个notification,每个handler都会在response中。你可使用下面的代码来实践一下并能看到最终的结果,若是你正在搞一个新项目,你能够把它放到Home Controller中。编码

public class SomeEvent : INotification {
    public SomeEvent(string message)
    {
        Message = message;
    }
 
    public string Message { get; }
}
 
public class Handler1 : INotificationHandler<SomeEvent>
{
    private readonly ILogger<Handler1> _logger;
 
    public Handler1(ILogger<Handler1> logger)
    {
        _logger = logger;
    }
    public void Handle(SomeEvent notification)
    {
        _logger.LogWarning($"Handled: {notification.Message}");
    }
}
public class Handler2 : INotificationHandler<SomeEvent>
{
    private readonly ILogger<Handler2> _logger;
 
    public Handler2(ILogger<Handler2> logger)
    {
        _logger = logger;
    }
    public void Handle(SomeEvent notification)
    {
        _logger.LogWarning($"Handled: {notification.Message}");
    }
}
 
 
public class HomeController : Controller
{
 
    private readonly IMediator _mediator;
 
    public HomeController(IMediator mediator)
    {
        this._mediator = mediator;
    }
    public async Task<IActionResult> Index()
    {
        await _mediator.Publish(new SomeEvent("Hello World"));
        return View();
    }
// more code omitted
}

上面的代码撸完后,使用kestrel运行你的应用(你能够在项目的根目录下面进入cmd而后输入dotnet run来启动一个控制台面板,或者在visual studio中改变启动方式,不过通常状况下我直接进到项目的properties目录下面找到lauchSettings.json,吧IIS相关的东西都删除了。)而后查看你的控制台面板的输出,你应该能看到输出的日志:spa

若是你只是想用MediatR来发布事件,上面的就是了。若是你想要看看怎么用它来作request/response,你须要在实现几个类:

public class Ping:IRequest<string>{}
public
class PingHandler : IRequestHandler<Ping, string> { public string Handle(Ping request) { return "Pong"; } } // optional to show what happens with multiple handlers public class Ping2Handler : IRequestHandler<Ping, string> { public string Handle(Ping request) { return "Pong2"; } }

上面的代码定义了一个request以及它的返回类型(string,IRequest<string>).handlers必须实现一个Handle方法,这个方法会返回指望的响应。当你发送一个请求,只有一个handler会被调用而且会返回一个带有合适类型的响应。

(做者在这里说明了一个问题,他给这个包的做者发了一个pull request要求若是有注册了多个handler,那么应该调用注册的第一个,由于只有第一个被添加到了DI系统中)。

当前的版本也不会抛出什么异常,可是即使在未来的版本中会抛出异常,也不会让我感到惊讶什么的。

不管以何种方式,要使用上面定义的内容,你只须要在About 方法中添加以下代码:

public async Task<IActionResult> About()
{
    // example of request/response messages
    var result = await _mediator.Send(new Ping());
    ViewData["Message"] = $"Your application description page: {result}";

    return View();
}

从浏览器中浏览/About页面,你能看到调用的结果。目前版本已经更正告终果,你将看到的是注册的第一个(按照你编码的从上到下的顺序,PingHandler是算第一个注册的)handler的返回的结果。

上面就是你要开始研究MediatR的一个很好的开端了。我已经火烧眉毛的想要将他运用在个人eShopContainer(微软示例项目,讲微服务的)项目当中了。查看这里 Microsoft’s architecture learning hub去获取更多微软的相关技术的书书籍吧。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Ping : IRequest < string > { }
public class PingHandler : IRequestHandler < Ping , string >
{
     public string Handle ( Ping request )
     {
         return "Pong" ;
     }
}
// optional to show what happens with multiple handlers
public class Ping2Handler : IRequestHandler < Ping , string >
{
     public string Handle ( Ping request )
     {
         return "Pong2" ;
     }
}
相关文章
相关标签/搜索