【翻譯】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" ;
     }
}
相關文章
相關標籤/搜索