Abp.VNext-发布自定义领域事件

案例场景

新注册用户注册时通过发布自定义领域事件发送邮件通知。

EntityFrameworkCore层

创建Etos文件夹,并在该文件夹下新增ChangeMode、DomainChangedEvent文件。

ChangeMode.cs

 public enum ChangeMode
 {
     Added,
     Updated,
     Deleted
 }

DomainChangedEvent.cs

 public interface IEto
 {

 }

 public class UserRegistChangedEto : IEto
 {
     public Guid UserId { get; set; }
 }

 public class DomainChangedEvent<TData> where TData : IEto
 {
     public DomainChangedEvent(ChangeMode changeMode)
     {
         ChangeMode = changeMode;
     }
     
     public TData Data { get; set; }
     
     public ChangeMode ChangeMode { get; set; }
 }
 

Application层

定义自定义事件处理程序

创建Handlers文件夹,并在该文件夹下新增EmailSendHandler.cs文件。

由于数据库操作和消息发送都在一个事务内,所以当消息发送成功之后,数据库事务操作才会被工作单元提交,如果消息发送出现异常,则会回滚工作单元,若不想回滚,需要在消息发送处加上try catch 抛出异常。

例如以下代码,发送邮件通知出现异常,则回滚工作单元,用户表也不会有用户数据。若希望发送邮件通知出现异常不影响到用户表数据的入库,则需要在发送邮件通知程序中加入try catch抛出异常。

UserService.cs

 public async Task<Guid> AddUserAsync(AddUserInputDto inputDto)
 {
     var entity = new SysUser();
     entity.Name = inputDto.UserName;
     entity.Password = inputDto.Pwd;
     entity.Sex = inputDto.sex;

     var user = await _userRepository.InsertAsync(entity);

     await _localEventBus.PublishAsync(
          new DomainChangedEvent<UserRegistChangedEto>(ChangeMode.Added)
          {
              Data = new UserInfoChangedEto { UserId = user.Id },
          });

     return user.Id;
 }

EmailSendHandler.cs

public class EmailSendHandler : ILocalEventHandler<DomainChangedEvent<UserRegistChangedEto>>, ITransientDependency
{
    private readonly ILogger<EmailSendHandler> _logger;

    public EmailSendHandler(ILogger<EmailSendHandler> logger)
    {
        _logger = logger;
    }

    public async Task HandleEventAsync(DomainChangedEvent<UserRegistChangedEto> eventData)
    {
        _logger.LogInformation(eventData.Data.ToJson());


        //发送邮件代码
        EmailUtil.SendEmail(eventData.Data.UserId);
        
        throw new AbpException("模拟异常");


        //try
        //{
        //    //发送邮件代码
        //    EmailUtil.SendEmail(eventData.Data.UserId);
        //    throw new AbpException("模拟异常");
        //}
        //catch (Exception ex)
        //{
        //    _logger.LogError(ex, ex.ToString());
        //}
    }

注意事项

  1. 领域事件发布是在工作单元成功提交之后发布,而不是在调用PublishAsync方法的时候发布。
posted @ 2024-11-19 17:40  相遇就是有缘  阅读(109)  评论(0)    收藏  举报