谷歌企业网站seo,WordPress博客程序优化,网站建设需要用到什么,wordpress无法改成中文字体1.引言
最近刚学习了下DDD中领域事件的理论知识#xff0c;总的来说领域事件主要有两个作用#xff0c;一是解耦#xff0c;二是使用领域事件进行事务的拆分#xff0c;通过引入事件存储#xff0c;来实现数据的最终一致性。若想了解DDD中领域事件的概念#xff0c;可参…1.引言
最近刚学习了下DDD中领域事件的理论知识总的来说领域事件主要有两个作用一是解耦二是使用领域事件进行事务的拆分通过引入事件存储来实现数据的最终一致性。若想了解DDD中领域事件的概念可参考DDD理论学习系列9-- 领域事件。 Abp中使用事件总线来实现领域事件而关于事件总线的实现大家可参考我这篇博文——事件总线知多少本文将不再赘述。
2.用例分析 当用户被成功分配任务后发送邮件和消息通知给用户。 这个用例比较简单没有太多的复杂逻辑按照我们传统的思路直接在任务编辑方法中添加邮件和消息发送的方法即可代码如下
public void UpdateTask(UpdateTaskInput input){ //We can use Logger, its defined in ApplicationService base class.Logger.Info(Updating a task for input: input); //获取是否有权限bool canAssignTaskToOther PermissionChecker.IsGranted(PermissionNames.Pages_Tasks_AssignPerson); //如果任务已经分配且未分配给自己且不具有分配任务权限则抛出异常if (input.AssignedPersonId.HasValue input.AssignedPersonId.Value ! AbpSession.GetUserId() !canAssignTaskToOther){ throw new AbpAuthorizationException(没有分配任务给他人的权限);} var updateTask Mapper.MapTask(input); var user _userRepository.Get(input.AssignedPersonId.Value); //先执行分配任务_taskManager.AssignTaskToPerson(updateTask, user); //再更新其他字段_taskRepository.Update(updateTask); //发送通知var message You hava been assigned one task into your todo list.;_smtpEmailSender.Send(ysjshengjieqq.com, updateTask.AssignedPerson.EmailAddress, New Todo item, message);_notificationPublisher.Publish(NewTask, new MessageNotificationData(message), null,NotificationSeverity.Info, new[] { updateTask.AssignedPerson.ToUserIdentifier() });
} 运行直接挂掉。原因是很清楚是由于邮箱配置有误导致。但是我们思考一下。我们进行任务分配时最关注的是任务被成功分配而至于通知是否成功发送相对来说是次要的。但是现在却由于通知发送失败导致任务无非被成功分配这是不合理的。
那我们要如何做呢当然是拆分业务逻辑。而这时领域事件就可以粉墨登场了。
3.使用领域事件
就这个用例而言“用户被成功分配任务”就是一个领域事件。下面我们就来实际应用一下。
3.1. 定义事件源
一个领域事件是通过事件源来识别的我们直接定义一个TaskAssignedEventData继承自EventData即可:
public class TaskAssignedEventData : EventData{ public User User { get; set; } public Task Task { get; set; } public TaskAssignedEventData(Task task, User user) { this.Task task; this.User user;}
}
3.2. 实现事件处理
定义TaskAssignedToUser事件处理实现IEventHandlerTaskAssignedEventData泛型接口即可
public class TaskAssignedToUser : IEventHandlerTaskAssignedEventData, ITransientDependency
{ private readonly ISmtpEmailSender _smtpEmailSender; private readonly INotificationPublisher _notificationPublisher; public TaskAssignedToUser(ISmtpEmailSender smtpEmailSender, INotificationPublisher notificationPublisher) {_smtpEmailSender smtpEmailSender;_notificationPublisher notificationPublisher;} public void HandleEvent(TaskAssignedEventData eventData) {var message You hava been assigned one task into your todo list.; //TODO:需要重新配置QQ邮箱密码_smtpEmailSender.Send(ysjshengjieqq.com, eventData.Task.AssignedPerson.EmailAddress, New Todo item, message);_notificationPublisher.Publish(NewTask, new MessageNotificationData(message), null,NotificationSeverity.Info, new[] { eventData.User.ToUserIdentifier() });}
}
3.3. 事件触发
我们可以直接在上一节定义的TaskManager领域服务中触发领域事件。因为这样更符合当前领域事件通用语言的表述。
//TaskManager.cspublic void AssignTaskToPerson(Task task, User user){ //已经分配就不再分配if (task.AssignedPersonId.HasValue task.AssignedPersonId.Value user.Id){ return;} if (task.State ! TaskState.Open){ throw new ApplicationException(处于非活动状态的任务不能分配);}task.AssignedPersonId user.Id; //使用领域事件触发发送通知操作_eventBus.Trigger(new TaskAssignedEventData(task, user));
}
再运行我们发现虽然没有接收到消息通知发送失败但任务却可以成功分配。
4. 一些问题
领域事件在哪注册订阅应用程序启动时Abp根据约定俗成的命名规则将事件源和事件处理注册到了依赖容器中和事件总线维护的容器中。我们也可以自行在应用服务或领域服务中手动注册。领域事件在哪触发发布事件的触发同样也没有限定根据需要可以在应用服务、领域服务、聚合、实体中发布。领域事件的命名领域事件的名字要反映出过去发生的事情的概念。
4.最后
由于demo比较简单找不到合适的用例以上使用的用例比较简单。在复杂的用例中当需要更新多个聚合时领域事件的作用就体现出来了借助领域事件我们可以很好的进行事务拆分达到最终一致性的目的。
而至于领域事件衍生出来的事件存储和事件溯源下次再和大家分享。
相关文章
DDD理论学习系列1-- 通用语言DDD领域驱动之干货 一DDD理论学习系列2-- 领域DDD理论学习系列3-- 限界上下文DDD理论学习系列4-- 领域模型事件总线知多少2DDD理论学习系列5-- 统一建模语言DDD理论学习系列6-- 实体DDD理论学习系列7-- 值对象DDD理论学习系列8-- 应用服务领域服务DDD理论学习系列9-- 领域事件从事件和DDD入手来构建微服务DDD领域驱动之干货 一WeText项目一个基于.NET实现的DDD、CQRS与微服务架构的演示案例【DDD/CQRS/微服务架构案例】在Ubuntu 14.04.4 LTS中运行WeText项目的服务端
原文地址http://www.cnblogs.com/sheng-jie/p/7136279.html .NET社区新闻深度好文微信中搜索dotNET跨平台或扫描二维码关注