闲话多说

领域事件大叔感觉是最不好讲的一篇文章,所以拖欠了很久,但最终还是在2015年年前(阴历)把这个知识点讲一下,事件这个东西早在C#1.0时代就有了,那时学起来也是一个费劲,什么是委托,哪个是事件,搞的大家是糊里糊涂,进入C#2.0时代后,大叔也买了一本书,对于delegate和event这两个知识点看了至少有20几遍,感觉稍微有点明白了,明白了其中的真谛和用意。

委托:方法的规范,方法的模板,可以代表一类方法的集合

事件:委托的实例,事件在使用之前需要为它赋值,当然赋的就是一个方法;事件可以注册和取消,当你注册一个事件之后,在事件被触发后,被注册的方法将会被执行,这一般被称为“方法的回调”,在设计模式里,又被称为“pub/sub模式”,即发布/订阅模式;在C#语言发展过程中,设计得为程序开发者考虑的很多,有些写法得到了精简,如Action和Func委托的出现之后,我们基本上告别了delegate,这对程序开发人员无疑是一件好事。

大叔框架中的事件

在大叔框架里,事件是常客,比如在早期的仓储代码里,你可以传递一个Action<string>的委托,来进行日志的记录,这种方法在IoC出现后,被大叔屏蔽了,原因不在这里说了,还有就是在N层架构里,WEB层与BLL层进行通讯时,WEB层通过HttpClient请求第三方的API获取数据,而BLL层的方法需要用到这个第三方API的返回值,而在BLL层直接访问HTTP显然是不合适的,所以,在WEB层到BLL层的方法参数设计时,需要有一个委托来接改从WEB层回调的方法返回值,这种代码一般称为“方法回调”。

web层向BLL层传入一个委托

  var entity = rechargeService.RechargeAuto(task,beforeTime,out result,(studentid, money) =>{//代码});

BLL层接改这个委托的返回值,代码在调用bll层这个方法时,首先会回调web层的http的方法

public Task_xuexiba_Recharge RechargeAuto(Task_Info task,DateTime beforeTime,out bool result,Func<int, decimal, RechargeXuexibaDTO> api){//代码}

  var apiEntity = api(task.Task_ParametersForXuexibaRecharge.StudentID, task.Task_ParametersForXuexibaRecharge.Money);

Lind.DDD框架里的领域事件

事件源后缀:Event

事件处理方法后缀:EventHandler

领域事件一般出现个领域实体里,在实体被建立时,会订阅和自己有关的事件,每个事件都有一个或者多个事件处理方法,事件处理方法可以进行数据库操作,或者网络和文件的操作,如发通知,写文件等,所以有时候我们的事件需要设计成异步的事件。

程序中的事件事件

  #region 领域模型public class Order{public Order(){Lind.DDD.Events.EventBus.Instance.Subscribe(new OrderInsertEventHandler());Lind.DDD.Events.EventBus.Instance.Subscribe<OrderPaid>(new OrderUpdateEventHandler());}public System.Guid Id { get; set; }public System.Guid UserId { get; set; }public string UserName { get; set; }public decimal TotalFee { get; set; }/// <summary>/// 用户提交并确认订单/// </summary>public void ComfirmOrder(){//事件发布Lind.DDD.Events.EventBus.Instance.Publish(new OrderConfirm{TotalFee = TotalFee,UserName = UserName,UserId = UserId,});}}#endregion

下面是领域事件源

   /// <summary>/// 订单被确认的事件源/// </summary>public class OrderConfirm : Lind.DDD.Events.IEvent{public override string ToString(){return "订单已经确认";}/// <summary>/// 订单总金额/// </summary>public decimal TotalFee { get; set; }/// <summary>/// 购买者ID/// </summary>public Guid UserId { get; set; }/// <summary>/// 购买者/// </summary>public string UserName { get; set; }#region IEvent 成员public Guid AggregateRoot{get { throw new NotImplementedException(); }}#endregion}

下面是领域事件的处理程序

   /// <summary>/// 订单被插入时的处理程序/// </summary>public class OrderInsertEventHandler :Lind.DDD.Events.IEventHandler<Events.OrderConfirm>{#region IEventHandler<OrderSigned> 成员public void Handle(Events.OrderConfirm evt){//处理訂單确认的逻辑var orderRepository = new Lind.DDD.Repositories.EF.EFRepository<Orders>();orderRepository.SetDataContext(new testEntities());orderRepository.Insert(new Orders{Id = Guid.NewGuid(),OrderStatus = 1,TotalFee = evt.TotalFee,UserId = evt.UserId,UserName = evt.UserName,});}#endregion}

如果希望将自己的事件处理程序设计成异常的,即不阻塞当前线程的,可以让它添加HandlesAsynchronouslyAttribute这个特性,如下面这个发送Email的处理程序就是一个异步的。

  /// <summary>/// 发邮件功能[某个事件的行为]/// </summary>
    [HandlesAsynchronouslyAttribute]public class SendEmailEventHandler :IEventHandler<OrderEvent>,IEventHandler<UserEvent>{#region IEventHandler<OrderEvent> 成员public void Handle(OrderEvent evt){Console.WriteLine("生成和确认订单{0}时发Email", evt.OrderId);}#endregion#region IEventHandler<UserEvent> 成员public void Handle(UserEvent evt){Console.WriteLine("建立用户后发Email,用户ID{0}", evt.UserId);}#endregion}

全局注册所有事件处理程序

这个是看完ABP之后的想法,原理是把BIN下所有继承了IEventHandler的类都自动注册到事件总线中,然后在事件被触发后,就自动执行你订阅的方法了,在项目开发过程中,推荐使用这种方法,但需要注意的是,你的事件处理程序必须是显示定义的,不能使用匿名的处理程序.

     /// <summary>/// 全局统一注册所有事件处理程序,实现了IEventHandlers的/// </summary>public void SubscribeAll(){var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IEventHandlers)))).Where(i => !Excepts.Contains(i.Name)).ToArray();foreach (var item in types){if (!item.ContainsGenericParameters){var en = Activator.CreateInstance(item);foreach (var t in item.GetInterfaces().Where(i => i.Name != "IEventHandlers")){Subscribe(t, en);}}}}

感谢各位的阅读!

本文转自博客园张占岭(仓储大叔)的博客,原文链接:Lind.DDD.Events领域事件介绍,如需转载请自行联系原博主。

Lind.DDD.Events领域事件介绍相关推荐

  1. Lind.DDD敏捷领域驱动框架~介绍

    最近觉得自己的框架过于复杂,在实现开发使用中有些不爽,自己的朋友们也经常和我说,框架太麻烦了,要引用的类库太多:之前架构之所以这样设计,完全出于对职责分离和代码附复用的考虑,主要参考了微软的DDD大作 ...

  2. Lind.DDD.Paging分页模块介绍

    分页组件网上有很多,MVC.Pager,JSPager等,通过实现方式大体分为前端分页和后端分页,前端分页是前台对list内存本地集合进行分页,缺点就是在大数据情况下,内存占用过高:后端分页就是UI把 ...

  3. Lind.DDD.Repositories.Mongo层介绍

    之前已经发生了 大叔之前讲过被仓储化了的Mongodb,而在大叔开发了Lind.DDD之后,决定把这个东西再搬到本框架的仓储层来,这也是大势所趋的,毕竟mongodb是最像关系数据库的NoSql,它的 ...

  4. Lind.DDD敏捷领域驱动框架~Lind.DDD各层介绍

    回到目录 Lind.DDD项目主要面向敏捷,快速开发,领域驱动等,对于它的分层也是能合并的合并,比之前大叔的框架分层更粗糙一些,或者说更大胆一些,在开发人员使用上,可能会感觉更方便了,更益使用了,这就 ...

  5. 殷浩详解DDD:领域层设计规范

    简介: 在一个DDD架构设计中,领域层的设计合理性会直接影响整个架构的代码结构以及应用层.基础设施层的设计.但是领域层设计又是有挑战的任务,特别是在一个业务逻辑相对复杂应用中,每一个业务规则是应该放在 ...

  6. DDD :领域层设计规范

    在一个DDD架构设计中,领域层的设计合理性会直接影响整个架构的代码结构以及应用层.基础设施层的设计.但是领域层设计又是有挑战的任务,特别是在一个业务逻辑相对复杂应用中,每一个业务规则是应该放在Enti ...

  7. ABP入门系列(19)——使用领域事件

    1.引言 最近刚学习了下DDD中领域事件的理论知识,总的来说领域事件主要有两个作用,一是解耦,二是使用领域事件进行事务的拆分,通过引入事件存储,来实现数据的最终一致性.若想了解DDD中领域事件的概念, ...

  8. java事件溯源_领域事件与事件溯源 - 解道Jdon

    领域事件.事件溯源.事件风暴建模 事件代表过去发生的事件,事件既是技术架构概念,也是业务概念.以事件为驱动的编程模型称为事件驱动架构EDA,事件驱动与事件溯源EventSourcing是两种概念,ED ...

  9. Lind.DDD.Domain领域模型介绍

    Lind.DDD.Domain位于Lind.DDD核心项目中,它主要面向领域实体而设计,由一个IEntity的标识接口,EntityBase基类和N个Entity实体类组成,其中IEntity主要用来 ...

最新文章

  1. 明晰软件架构与数据结构
  2. JavaScript中函数的变量提升问题
  3. Apache2+PHP5不能加载Zend Optimizer的问题
  4. javafx如何带菜单_JavaFX技巧30:带有DropShadow的ScrollPane
  5. 聘用计算机高级职称,关于咨询高级职称聘用的问题
  6. [SQL Server]用于压力测试和性能分析的两个支持实用工具[转]
  7. iOS页面间跳转的方式
  8. Camera 初始化(Open)一(FrameWork - Hal)
  9. sql与MySQL like用法_MySQL中Like概念及用法讲解
  10. Nginx(1)— Nginx工作原理
  11. 项目管理第五章项目范围管理
  12. 2017服务器cpu性能排行,桌面CPU性能排行 CPU天梯图2017年7月最新版
  13. librosa 语音库(二)STFT 的实现
  14. 安装oracle客户端此先决条件,xp系统下oracle 11g客户端安装先决条件检查全部失败...
  15. 其他人的爱情 VS 程序员的爱情
  16. JavaScript 实现抢购倒计时,记录恋爱1314纪念日倒计时,输出对应的天数小时分钟秒数
  17. Firefly互动广告机解决方案
  18. 国产数据库kingbase
  19. U盘/移动硬盘安装CentOS系列系统
  20. Numpy库的介绍及使用

热门文章

  1. python中beautifulsoup是什么,Python Beautiful Soup简介
  2. 对C#、.Net、.Net Frameworke、托管和非托管代码的具体理解
  3. 打印机无法打印PDF格式的电子发票问题
  4. 鱼眼畸变矫正-S样板图处理小记
  5. Java 对类的重命名
  6. 2020年自考专科可以自考本科吗丨自考专科、自考本科能同时考吗
  7. 【问题解决】PPT错误,应用程序无法正常启动(0xc0000022)
  8. 河北工程科技学院计算机专业,计算机科学与技术系与河北工程大学信息与电气工程学院联合召开一流专业建设交流会...
  9. [WinCE] Win CE 屏幕截图
  10. VMware Workstation pro无法在Windows上运行,检查可在Windows上运行的此应用的更新版本