Lind.DDD.Events领域事件介绍

简介:

闲话多说

领域事件大叔感觉是最不好讲的一篇文章,所以拖欠了很久,但最终还是在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领域事件介绍,如需转载请自行联系原博主。

目录
相关文章
|
3月前
|
人工智能 Ubuntu API
从零开始:在Ubuntu上快速部署Docker和Dify
本文介绍了如何在 Ubuntu 环境下通过阿里云镜像快速安装 Docker 与 Docker Compose,并部署 Dify 智能应用平台。结合蓝耘 MaaS 平台 API,实现大模型高效接入,帮助开发者快速构建 AI 应用,提升开发效率与使用体验。
1241 8
|
Web App开发 测试技术 API
Playwright 测试报告中显示的标签和注释。
Playwright 测试报告中显示的标签和注释。
271 57
|
10月前
|
人工智能 运维 机器人
《深度剖析:人工智能与人类协作模式的未来演变》
人工智能与人类的协作正经历从辅助工具到平等伙伴、特定领域到多领域融合、静态协作到动态自适应、工作场景到全场景渗透的演变。初期,AI作为高效助手处理重复任务;中期成为得力伙伴,参与医疗、科研等领域的深度协作;未来将作为平等团队成员,在智慧城市、智能家居等多领域实现跨模态协作,动态调整任务分配,全面融入生活和工作,创造更多可能性。
811 15
|
人工智能 安全 量子技术
大疆DJI无人机等你来拿,蚂蚁集团agentUniverse 多智能体框架有奖征文
agentUniverse有奖征文活动来啦!分享agentUniverse的实践经验、亦或是剖析市面上各路智能体技术理念、对比开源框架的洞见,都有机会获得大疆无人机!
大疆DJI无人机等你来拿,蚂蚁集团agentUniverse 多智能体框架有奖征文
|
机器人 测试技术 开发者
ModelScope中文模型测评
Modelscope可以帮助研究人员和开发者对模型进行性能分析等。本次我体验了知识常识,人类价值观和写作创作相关这三个对话类型场景,下面是我对测试模型的分析与看法
446 1
 ModelScope中文模型测评
|
开发框架 Java Android开发
Java中的类反射与动态代理详解
Java中的类反射与动态代理详解
|
域名解析 负载均衡 网络协议
分布式与集群,二者区别是什么?
分布式与集群,二者区别是什么?
|
关系型数据库 分布式数据库 网络安全
PolarDB产品使用问题之如何设置优先级数据库节点
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
201 0
|
Java 数据库连接 数据库
数据安全之舞:Spring事务处理的实用指南与技术要点
数据安全之舞:Spring事务处理的实用指南与技术要点
134 0
数据安全之舞:Spring事务处理的实用指南与技术要点
|
数据采集 数据可视化 数据挖掘
知识分享-商业数据分析业务全流程
知识分享-商业数据分析业务全流程
324 1

热门文章

最新文章