events - CQRS 中的事件版本控制

标签 events domain-driven-design versioning cqrs

我们正处于开发周期(asp.net mvc 应用程序)的某个阶段,我们需要对现有命令和事件进行更改(例如添加/删除一些属性等)。

我一直试图找到一种方法来在系统中引入命令/事件版本控制。我已经阅读了很多关于 google/stackoverflow 等的帖子,但我仍然看到了一个实现它的代码示例。版本控制时是否应遵循推荐的模式。如果是,有任何示例/片段吗?

编辑:这是我得到的程度

  • 我已经将我的事件向后版本化,这样最新的将始终被称为相同的,而过时的将添加一个后缀,如“_V1”、“_V2”等。

  • 所以如果我有一个事件
    public class OrderSubmittedEvent : IDomainEvent
    {
        public int OrderId { get; private set; }
    
        public OrderSubmittedEvent(int orderId)
        {
            OrderId = orderId;
        }
    }
    

    如果我必须添加一些属性,我将上面的事件重命名为
    public class OrderSubmittedEvent_V1 : IDomainEvent
    {
        public int OrderId { get; private set; }
    
        public OrderSubmittedEvent_V1(int orderId)
        {
            OrderId = orderId;
        }
    }
    

    并引入另一个与我的原始事件同名但添加了属性的事件,就像这样
    public class OrderSubmittedEvent : IDomainEvent
    {
        public int OrderId { get; private set; }
    
        public OrderSubmittedEvent(int version = 1, int orderId = 0, string customerName =  
                                   "Joe blogs", string address = "Earth")
        {
            OrderId = orderId;
            CustomerName = customerName;
            Address = address;
            CurrentVersion = version;
        }
    
        public static int LatestVersion
        {
            get { return 2; }
        }
    
        public int CurrentVersion { get; set; }
    
        public string CustomerName { get; set; }
        public string Address { get; set; }
    }
    

    我仍然必须继续更改我发布此事件的代码以包含新属性的值。
  • 在任何给定的时间点,当我从事件存储中获取我的所有事件(例如,用于重播)时,它们在反序列化(在本例中为 OrderSubmittedEvent)后将始终是相同类型的,并且具有不属于旧事件的一部分的新属性填充它们的默认值。

  • 在重播我的事件时,我让我的事件通过 IEventUpgrader
    这首先验证事件是否是可用的最新版本。由于类型将始终是事件类型,因此此检查基于属性“LatestVersion”和“CurrentVersion”

    大家怎么看这种方法?

    下一个待办事项
  • 如果事件是旧版本,则发布“UpdateMYEVENT”事件

  • 谢谢

    最佳答案

    通常你只需要对事件进行版本控制,你可以忽略这些命令,因为你没有将它们存储在事件存储中。

    实现版本控制的方法很少。我的方法很简单:

    [Obsolete]
    public class CompanyCreated
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }
    
    public class CompanyCreated_V2
    {
        public Guid Id { get; set; }
        public string CompanyName { get; set; }
        public string TaxNumber { get; set; }
    }
    

    当您从事件存储中读取事件时,您需要处理从旧事件到新事件的转换。

    此外,您需要注意,您永远不会删除任何旧的事件类,因此我将它们装饰为 Obsolete,以让其他开发人员知道不要使用该事件。

    关于events - CQRS 中的事件版本控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16520937/

    相关文章:

    c# - 为什么 Winforms Click 事件比 MouseClick 事件慢?

    nhibernate - nhibernate 的双向关系模式

    domain-driven-design - 保持聚合之间的一致性

    ruby-on-rails - Rails - 存在路由时 API 命名空间的路由错误

    java - 如何添加全局 Action 事件监听器?

    oop - Action 和事件有什么区别?

    javascript - 处理 JavaScript 中按钮点击的最佳方式(vanilla)

    domain-driven-design - ApplicationEvent 与 DomainEvent 有何不同?

    hadoop - 数据版本控制(Hadoop、HDFS、Hbase 后端)

    sql-server - SQL Server 中的完整数据库版本控制