- Published on
ASP.NET Core 使用 MediatR 實作消息通知
在之前的文章 ( ASP.NET Core 使用 MediatR 簡單的實現 Clean Architecture、CQRS 和分層架構 ) 已經有介紹基本的 MediatR
的用法了,現在要介紹的是它的消息通知功能
範例 Repository 在 Github
新增 Person 的通知 BusinessLogic
模擬新增 Person 之後要發 Mail 和送到 MQ
- 建立
AddPersonNotification
,實作 MediatR 的INotification
public class AddPersonNotification : INotification
{
public AddPersonNotification(Person person)
{
Id = person.Id;
Name = person.Name;
}
public int Id { get; private set; }
public string Name { get; private set; }
}
- 建立
AddPersonMailNotificationHandler
,來處理AddPersonNotification
,需要實作 MediatR 的INotification
,會需要實作一個 Handle 的方法,方法第一個參數就是實作INotification
的類別 (泛型參數)- 泛型參數是實作 INotification 的
AddPersonNotification
- 內容不是我們的重點,直接使用
Console.WriteLine
印出來,實際上請換成自己要執行的程式碼
- 泛型參數是實作 INotification 的
public class AddPersonMailNotificationHandler : INotificationHandler<AddPersonNotification>
{
public Task Handle(AddPersonNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine("Mail Notification");
return Task.CompletedTask;
}
}
- 建立
AddPersonMqNotificationHandler
,方式和AddPersonMailNotificationHandler
一樣
public class AddPersonMqNotificationHandler : INotificationHandler<AddPersonNotification>
{
public Task Handle(AddPersonNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine("Mq Notification");
return Task.CompletedTask;
}
}
修改新增 Person 的 CommandHandler BusinessLogic
- constructor 注入
IMediator
- 使用 Mediator 的
Publish
方法,把需要處理的物件丟進去 (也就是實作INotification
的物件),因為沒有回傳值,就直接 await 它就好
public class AddPersonCommandHandler : IRequestHandler<AddPersonCommand, Unit>
{
private readonly AppDbContext _dbContext;
private readonly IMediator _mediator;
public AddPersonCommandHandler(AppDbContext dbContext, IMediator mediator)
{
_dbContext = dbContext;
_mediator = mediator;
}
public async Task<Unit> Handle(AddPersonCommand request, CancellationToken cancellationToken)
{
var person = new Person { Id = request.Id, Name = request.Name };
await _dbContext.Person.AddAsync(person, cancellationToken);
await _dbContext.SaveChangesAsync(cancellationToken);
await _mediator.Publish(new AddPersonNotification(person), cancellationToken);
return Unit.Value;
}
}
- 實際新增 Person 測試,可以看到有印出兩個 Notification
多個 Notification 的問題
預設處理 Notification 時,會等每一個處理的 Handler 都執行完成。如果這不是你想要的執行方式,可以參考官網的 MediatR.Examples.PublishStrategies 程式碼,修改自己的程式碼,達到下面這 6 種策略