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());
//}
}
注意事项
- 领域事件发布是在工作单元成功提交之后发布,而不是在调用PublishAsync方法的时候发布。
人生如逆旅
我亦是行人

浙公网安备 33010602011771号