ASP.NET Core用MediatR实现领域事件
目录
领域事件的实现选择
实现方式1:C#的事件机制
实现方式2:进程内消息传递的开源库MediatR。
MediatR用法
注意
领域事件的实现选择
实现方式1:C#的事件机制
缺点:需要显式地注册。
var bl = new ProcessBusinessLogic();
bl.ProcessCompleted += bl_ProcessCompleted;
bl.StartProcess();
实现方式2:进程内消息传递的开源库MediatR。
事件的发布和事件的处理之间解耦。MediatR中支持“一个发布者对应一个处理者”和“一个发布者对应多个处理者”这两种模式。
MediatR用法
- NuGet:MediatR
- Program.cs中调用AddMediatR()
builder.Services.AddMediatR(cfg => { cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()); });
- 定义一个在消息的发布者和处理者之间进行数据传递的类,这个类需要实现INotification接口。一般用record类型。
public record PostNotification(string Body) : INotification;
- 消息的处理者要实现NotificationHandler<TNotification>接口,其中的泛型参数TNotification代表此消息处理者要处理的消息类型。
public class PostNotifHandler1 : NotificationHandler<PostNotification> { protected override void Handle(PostNotification notification) { Console.WriteLine("111"+notification.Body); } }
- 在需要发布消息的的类中注入IMediator类型的服务,然后我们调用Publish方法来发布消息。Send()方法是用来发布一对一消息的,而Publish()方法是用来发布一对多消息的。
[Route("api/[controller]/[action]")] [ApiController] public class DemoController : ControllerBase { private readonly IMediator mediator; public DemoController(IMediator mediator) { this.mediator = mediator; } [HttpGet] public ActionResult Get() { await mediator.Publish(new PostNotification("你好呀" + DateTime.Now)); return Ok(); } }
注意
如果使用await来调用Publish,程序会等待所有事件处理者的Handle方法执行完成才继续向后执行,因此事件发布者和事件处理者的代码是运行在相同的调用堆栈中的,这样可以轻松实现强一致性的事务。如果不需要等待事件处理者的执行,可以不使用await来在调用Publish;即使使用await调用Publish发布事件,如果某个事件处理者的代码执行太耗时,为避免影响用户体验,可以在事件处理者的Handle方法中异步执行事件的处理逻辑。如果不等待事件处理者,就要处理事务的最终一致性。