Event versioning in CQRS

We are at the point of our development cycle (asp.net mvc applciation), where we need to make changes to our existing commands and events (for example, adding / removing several properties, etc.).

I am trying to find a way to introduce version control of commands / events in the system. I read a lot of posts about google / stackoverflow etc., but I still see sample code that implements it. Is there a recommended model to follow when managing versioning? If yes, then any examples / snippets?

Edit: this is how far I got with this

  • I brought my events back, so that the latter will always be called the same, while those that are outdated will have a suffix added to it, for example, "_V1", "_V2", etc.

So, if I have an event

public class OrderSubmittedEvent : IDomainEvent { public int OrderId { get; private set; } public OrderSubmittedEvent(int orderId) { OrderId = orderId; } } 

and if I need to add some properties, rename my event above to

 public class OrderSubmittedEvent_V1 : IDomainEvent { public int OrderId { get; private set; } public OrderSubmittedEvent_V1(int orderId) { OrderId = orderId; } } 

and enter another event with the same name as my original event, but with added properties, for example

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

I still need to continue and change my code that publishes this event to include values ​​for new properties.

  • any given point in time when I get all my events from the event store (say, for replay), they will always be of the same type after deserialization (in this case OrderSubmittedEvent) with new properties that were not part of the old event, filled with their default values.

While playing back my events, I do my events through IEventUpgrader First it checks to see if the latest version is available. since the type will always be the event type, this check is based on the LastVersion and CurrentVersion properties

What does everyone think of this approach?

next todo

  • If the event is an old version, post the UpdateMYEVENT event

thanks

+4
source share
4 answers

usually you only need to update events, you can ignore commands since you do not store them in the event store.

There are several ways to implement versions. My method is pretty simple:

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

You need to handle the conversion of events from old to new when you read events from the event repository.

In addition, you need to know that you never delete old event classes, so I decorate them as deprecated so that other developers do not know how to use this event.

+6
source

If you only add and remove properties, there may not be a need for version events; just ignore serialized properties that are removed, and use reasonable defaults for the ones you add.

+4
source

Admittedly, I did not have the opportunity to try the following, but I would like to bake in the version from day one:

Since the full type name is relevant, I would go to the namespace.

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

They can be in different assemblies, and you can mark older ones as obsolete (as Sarmaad suggests). Perhaps the old version is not necessarily out of date.

Any ideas?

+1
source

I am completely for reasons, considering why it was necessary to manage events in the way it was set, and more specifically, as suggested in the answers?

I can only think of two use cases

1- the currently used event class is outdated and is no longer needed. This class can then be tracked in git at any time. So, why bother and complicate the active code while preserving dead classes?

2- The business requirements have changed, and now you need to save the base event, but you also need another similar event with some differences in the parameters. This can be solved in several ways, for example, the decorator’s pattern can help to cope with such options to a large extent. Alternatively, a new event can be a unique concept of a domain, and instead of trying to fix the concept in an existing model, it would be better to call it more semantically and use it that way.

0
source

Source: https://habr.com/ru/post/1480458/


All Articles