2013-05-13 56 views
4

我們正處於開發週期的一個階段(asp.net mvc applciation),我們需要對現有命令和事件(例如添加/刪除一些屬性等)進行更改。CQRS中的事件版本控制

我一直在試圖找到一種方法來在系統中引入命令/事件版本控制。我已經閱讀了谷歌/ stackoverflow等很多帖子,但我仍然看到一個實現它的代碼的例子。版本控制時應該遵循一個推薦的模式。如果是的話,任何示例/片段?

編輯:這是我在多大程度上與此

  1. 得到我已經向後版本我的事件,例如,最新的總是被稱爲是相同的,而走過時的人都會有加一個後綴它像「_V1」,「_V2」等

所以,如果我有一個事件

public class OrderSubmittedEvent : IDomainEvent 
{ 
    public int OrderId { get; private set; } 

    public OrderSubmittedEvent(int orderId) 
    { 
     OrderId = orderId; 
    } 
} 

,如果我需要添加一些屬性重新命名我的事件AB奧雅納到

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; } 
} 

我還是要繼續前進,改變我的代碼發佈此事件包括新屬性的值。

  1. 當我從事件存儲我的所有事件(比如,重播)任何給定時間點,他們將永遠是反序列化後的同一類型(在這種情況下OrderSubmittedEvent)與不部分新特性以默認值填充的舊事件。

在重播我的活動時,我讓我的活動通過一個IEventUpgrader 這首先驗證事件是否是最新版本可用。因爲類型將始終是事件類型,所以此檢查基於屬性「LatestVersion」和「CurrentVersion」

大家對這種方法有何看法?

下一個待辦事項

  1. 如果事件是舊版本發佈的「UpdateMYEVENT」事件

感謝

+0

您是使用事件採購還是隻使用消息驅動的CQRS? – MikeSW 2013-05-14 08:45:09

+0

@MikeSW - 只是消息驅動CQRS – 2013-05-14 15:24:41

回答

6

通常你只需要版本的事件,你可以忽略,因爲該命令你不會將它們存儲在事件存儲中。

有實現版本..我的方法是相當簡單的幾種方法:

[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,以便讓其他開發人員知道不使用該事件。

+0

@感謝您的回覆。我更新了主要問題,我的編輯 – 2013-05-14 15:39:16

+0

@nesh_s不知道爲什麼你想要「向後」版本,我認爲它會增加混淆。此外,您的IEventUpgrader將始終知道源和目標類型。事件本身不應該有任何知識的版本號或持有任何基礎設施信息。這是IEventUpgrader作爲更多基礎設施服務的角色。從技術上講,您提出的解決方案沒有任何問題,只要記住維護,關注事項和訂閱者的分離。 – Sarmaad 2013-05-15 06:27:41

+0

有趣。我想使用向後版本來確保我不必每次添加新版本時都要更改引用(使用事件的地方)。當我的事件被命名爲版本號時,如何不知道它自己的版本號?你的意思是沒有財產?這是我跟蹤最新版本號的唯一途徑。 – 2013-05-15 08:22:06

4

如果您只是添加&刪除屬性,可能不需要版本事件;只是忽略已刪除的序列化屬性,並對所添加的屬性使用合理的默認值。

1

誠然,我還沒有機會嘗試下,但我想從一開始的版本去烤:

由於全類型名稱是相關的,我會去的命名空間。

namespace Primary.Messages.V1 
{ 
    public class CompanyCreated 
    { 
     public Guid Id { get; set; } 
     public string Name { get; set; } 
    } 
} 

namespace Primary.Messages.V2 
{ 
    public class CompanyCreated 
    { 
     public Guid Id { get; set; } 
     public string Name { get; set; } 
     public string TaxNumber { get; set; } 
    } 
} 

這些可能在不同的程序集中,您可以將舊的標記爲過時(如Sarmaad所建議的)。這可能是舊版本不一定是過時的。

任何想法?

+0

完全同意你的看法 – paul 2016-01-09 13:49:53

0

我完全沒有理由考慮爲什麼需要事件版本化的方式有問題,更具體地說,它已被建議在答案中的方式?

我能想到的只有兩個用例

1 - 當前正在使用的事件類已被棄用,不再需要。 然後,可以隨時在git中追蹤該類。那麼爲什麼要通過保持死亡類來干擾並使活動代碼複雜化呢?

2-業務需求已更改,現在您需要保留基本事件,但您還需要另一個具有某些參數差異的類似事件。 這可以通過很多方式解決,比如修飾器模式可以幫助很大程度地處理這種變化 或者,新事件可能代表一個獨特的域概念,而不是試圖強制概念進入現有模型,它可能更好地命名它的語義和使用它的方式。