静态类DomainEvents:

public static class DomainEvents
    {
        [ThreadStatic]
        private static List<Delegate> _actions;
        private static List<Delegate> Actions
        {
            get
            {
                if (_actions == null)
                {
                    _actions = new List<Delegate>();
                }
                return _actions;
            }
        }

        public static IDisposable Register<T>(Action<T> callback)
        {
            Actions.Add(callback);
            return new DomainEventRegistrationRemover(
                () => Actions.Remove(callback)
                );
        }

        public static void Raise<T>(T eventArgs)
        {
            foreach(Delegate action in Actions)
            {
                (action as Action<T>)?.Invoke(eventArgs);
            }
        }

        private sealed class DomainEventRegistrationRemover : IDisposable
        {
            private readonly Action _callOnDispose;

            public DomainEventRegistrationRemover(Action toCall)
            {
                _callOnDispose = toCall;
            }

            public void Dispose()
            {
                _callOnDispose();
            }
        }
    }

实体OrderForDelivery:

public class OrderForDelivery
    {
        public Guid OrderId { get; set; }
        public FoodDeliveryOrderSteps Status { get; set; }
        public DateTime TimeThatPizzaWasDeliverd { get; set; }
        public DateTime TimeOfOrderBeingPlaced { get; set; }

        //public delegate void DeliveryGuaranteeFailedHandler(DeliveryGuaranteeFailed evnt);
        //public event DeliveryGuaranteeFailedHandler DeliveryGuaranteeFailed;

        public void ConfirmReceipt(DateTime timeThatPizzaWasDelivered)
        {
            if(Status!=FoodDeliveryOrderSteps.Delivered)
            {
                TimeThatPizzaWasDeliverd = timeThatPizzaWasDelivered;
                Status = FoodDeliveryOrderSteps.Delivered;
                if(DeliveryGuaranteeOffer.IsNotSatisfiedBy(TimeOfOrderBeingPlaced,TimeThatPizzaWasDeliverd))
                {
                    DomainEvents.Raise(new DeliveryGuaranteeFailed(this));
                }
            }
        }
    }

仓储MyOrderRepository:

public class MyOrderRepository : IOrderRepository
    {
        private List<OrderForDelivery> orderList=new List<OrderForDelivery>();
        public void AddOrder(OrderForDelivery order)
        {
            orderList.Add(order);
        }
        public OrderForDelivery FindBy(Guid orderId)
        {
            return orderList.SingleOrDefault(x => x.OrderId == orderId);
        }
    }

仓储接口IOrderRepository:

public interface IOrderRepository
    {
        OrderForDelivery FindBy(Guid orderId);
    }

领域服务ConfirmDeliveryOfOrder:

public class ConfirmDeliveryOfOrder
    {
        private IOrderRepository orderRepository;
        public ConfirmDeliveryOfOrder(IOrderRepository repo)
        {
            this.orderRepository = repo;
        }
        public void Confirm(DateTime timeThatPizzaWasDelivered,Guid orderId)
        {
            using (DomainEvents.Register<DeliveryGuaranteeFailed>(onDeliveryFailure))
            {
                var order = orderRepository.FindBy(orderId);
                order.ConfirmReceipt(timeThatPizzaWasDelivered);
            }
        }

        private void onDeliveryFailure(DeliveryGuaranteeFailed evnt)
        {
            Console.WriteLine("送餐超时了...");
        }
    }

错误定义DeliveryGuaranteeFailed:

public class DeliveryGuaranteeFailed
    {
        public DeliveryGuaranteeFailed(OrderForDelivery order)
        {
            this.Order = order;
        }
        public OrderForDelivery Order { get; private set; }
    }

状态枚举FoodDeliveryOrderSteps:

public enum FoodDeliveryOrderSteps
    {
        UnDeliver,
        Delivered
    }

条件判断DeliveryGuaranteeOffer:

public class DeliveryGuaranteeOffer
    {
        public static bool IsNotSatisfiedBy(DateTime timeOfOrderBeingPlaced, DateTime timeThatPizzaWasDeliverd)
        {
            return timeOfOrderBeingPlaced < timeThatPizzaWasDeliverd;
        }
    }

应用层Main():

static void Main(string[] args)
        {
            OrderForDelivery order = new OrderForDelivery()
            {
                OrderId = Guid.NewGuid(),
                Status = FoodDeliveryOrderSteps.UnDeliver,
                TimeOfOrderBeingPlaced = , , , , , )
            };
            MyOrderRepository repo = new MyOrderRepository();
            repo.AddOrder(order);
            ConfirmDeliveryOfOrder confirm = new ConfirmDeliveryOfOrder(repo);
            confirm.Confirm(, , , , , ), order.OrderId);
            Console.ReadKey();
        }

不使用DomainEvents:

public class OrderForDelivery
    {
        public Guid OrderId { get; set; }
        public FoodDeliveryOrderSteps Status { get; set; }
        public DateTime TimeThatPizzaWasDeliverd { get; set; }
        public DateTime TimeOfOrderBeingPlaced { get; set; }

        public delegate void DeliveryGuaranteeFailedHandler(DeliveryGuaranteeFailed evnt);
        public event DeliveryGuaranteeFailedHandler DeliveryGuaranteeFailed;

        public void ConfirmReceipt(DateTime timeThatPizzaWasDelivered)
        {
            if(Status!=FoodDeliveryOrderSteps.Delivered)
            {
                TimeThatPizzaWasDeliverd = timeThatPizzaWasDelivered;
                Status = FoodDeliveryOrderSteps.Delivered;
                if(DeliveryGuaranteeOffer.IsNotSatisfiedBy(TimeOfOrderBeingPlaced,TimeThatPizzaWasDeliverd))
                {
                    //DomainEvents.Raise(new DeliveryGuaranteeFailed(this));
                    DeliveryGuaranteeFailed(new DomainService.DeliveryGuaranteeFailed(this));
                }
            }
        }
public class ConfirmDeliveryOfOrder
    {
        private IOrderRepository orderRepository;
        public ConfirmDeliveryOfOrder(IOrderRepository repo)
        {
            this.orderRepository = repo;
        }
        public void Confirm(DateTime timeThatPizzaWasDelivered,Guid orderId)
        {
            var order = orderRepository.FindBy(orderId);
            order.DeliveryGuaranteeFailed += onDeliveryFailure;
            order.ConfirmReceipt(timeThatPizzaWasDelivered);
            //using (DomainEvents.Register<DeliveryGuaranteeFailed>(onDeliveryFailure))
            //{
            //    var order = orderRepository.FindBy(orderId);
            //    order.ConfirmReceipt(timeThatPizzaWasDelivered);
            //}
        }

        private void onDeliveryFailure(DeliveryGuaranteeFailed evnt)
        {
            Console.WriteLine("送餐超时了...");
        }
    }

领域事件DomainEvents的更多相关文章

  1. ABP框架 - 领域事件(EventBus)

    文档目录 本节内容: EventBus 注入 IEventBus 获取默认实例 定义事件 预定义事件 处理完异常 实体修改 触发事件 处理事件 处理基类事件 处理程序异常 处理多个事件 处理程序注册 ...

  2. 如何一步一步用DDD设计一个电商网站(十三)—— 领域事件扩展

    阅读目录 前言 回顾 本地的一致性 领域事件发布出现异常 订阅者处理出现异常 结语 一.前言 上篇中我们初步运用了领域事件,其中还有一些问题我们没有解决,所以实现是不健壮的,下面先来回顾一下. 二.回 ...

  3. DDD领域驱动设计:领域事件

    1 前置阅读 在阅读本文章之前,你可以先阅读: DDD领域驱动设计是什么 DDD领域驱动设计:实体.值对象.聚合根 DDD领域驱动设计:仓储 MediatR一个优秀的.NET中介者框架 2 什么是领域 ...

  4. 重新整理 .net core 实践篇—————领域事件[二十九]

    前文 前面整理了仓储层,工作单元模式,同时简单介绍了一下mediator. 那么就mediator在看下领域事件启到了什么作用吧. 正文 这里先注册一下MediatR服务: // 注册中间者:Medi ...

  5. ABP(现代ASP.NET样板开发框架)系列之14、ABP领域层——领域事件(Domain events)

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之14.ABP领域层——领域事件(Domain events) ABP是“ASP.NET Boilerplate P ...

  6. ABP理论学习之事件总线和领域事件

    返回总目录 本篇目录 事件总线 定义事件 触发事件 处理事件 句柄注册 取消注册 在C#中,我们可以在一个类中定义自己的事件,而其他的类可以注册该事件,当某些事情发生时,可以通知到该类.这对于桌面应用 ...

  7. Lind.DDD.Events领域事件介绍

    回到目录 闲话多说 领域事件大叔感觉是最不好讲的一篇文章,所以拖欠了很久,但最终还是在2015年年前(阴历)把这个知识点讲一下,事件这个东西早在C#1.0时代就有了,那时学起来也是一个费劲,什么是委托 ...

  8. DDD~领域事件与事件总线

    回到目录 谈谈它 终于有些眉目了,搜刮了很多牛人的资料,英文的,中文的,民国文的,终于小有成就了,同时也做了个DEMO,领域事件这东西好,但需要你明白它之后才会说好,而对于明白领域事件这件事来说,它的 ...

  9. DDD~领域事件应用篇(订单处理变得更清晰)

    回到目录 上一讲主要说了领域事件和领域总线,这并不是一个很容易理解的文章,所以本讲实例篇主要是为了补充上一讲的理论知识,本讲实例关注的是实际中的订单处理模块,我们知道,订单处理是电子商务的核心,往往在 ...

随机推荐

  1. noip2008普及组4题题解-rLq

    (啊啊啊终于补到了今天的作业了) 本题地址:http://www.luogu.org/problem/show?pid=1058 题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣 ...

  2. java读取word内容

    暂时只写读取word内容的方法. 依赖的jar: poi-3.9-20121203.jarpoi-ooxml-3.9-20121203.jarxmlbeans-2.3.0.jar package co ...

  3. selenium处理滚动条

    1.用js实现 滚动到底部 String js="document.documentElement.scrollTop=10000"滚动到顶部 String js="do ...

  4. [推荐] BC/Beyond Compare(差异比较软件)

    Beyond Compare 前一段时间,介绍过用Total Commander来完成文件夹同步的时候,一位朋友留言推荐了Beyond Compare--一个强大的超越了文件差异比较的工具.Beyon ...

  5. Unity抗锯齿

    Unity抗锯齿设置是针对模型,对模型的阴影的锯齿设置无效,不知道我这样的理解是否正确. 遇到的问题 而我是要对灯光照射在模型上产生的阴影进行抗锯齿,暂时还未研究出解决方案,希望知道的朋友告知一声. ...

  6. 浅谈CLR

    1.什么是CLR CLR(Common Language Runtime)公共语言远行时,是一个可由多种编程语言使用的“远行时”.CLR的核心功能(比如内存管理.程序集加载.安全性.异常处理和线程同步 ...

  7. mysql数据库的备份和导入

    mysqldump -u root -p --default-character-set = gbk -d demo_db>c:/appserv/www/demosql/sql1.sql//将数 ...

  8. 20Spring_JdbcTemplatem模板工具类

    JdbcTemplate 是Spring提供简化Jdbc开发模板工具类.为了更好的了解整个JdbcTemplate配置数据库连接池的过程,这篇文章不采用配置文件的方式,而是采用最基本的代码 的方式来写 ...

  9. 神奇的main方法详解

    main函数的详解:    public : 公共的. 权限是最大,在任何情况下都可以访问.        原因: 为了保证让jvm在任何情况下都可以访问到main方法.    static:  静态 ...

  10. C#报错:创建调试信息文件 ……obj\Debug\model.pdb: 拒绝访问

    错误:创建调试信息文件“.......\obj\Debug\model.pdb”时发生错误 --“......\obj\Debug\model.pdb: 拒绝访问. 解决办法如下: 删除该项目下的 b ...