Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event versioning in CQRS

We are at a point in our development cycle (asp.net mvc applciation), where we need to introduce changes to our existing commands and events (say adding/removing a few properties etc).

I have been trying to find a way to introduce commands/events versioning in the system. I have read many posts on google/stackoverflow etc but am still to see an example of code that implements it. Is there a recommended pattern one should follow when versioning. If yes any examples/snippets?

Edit: This is how far i have gotten with this

  1. i have versioned my events backwards, such that the latest will always be called the same, while the ones that go obsolete will have a suffix added to it like '_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 have to add a few properties i rename my event above to

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

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

and introduce another event with the same name as my original event but with added properties, like so

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 have to go ahead and change my code which publishes this event to include values for new properties.

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

At the time of replaying my events i make my events go through an IEventUpgrader This first verifies if the events is the latest version available. since the type will always be the event type, this check is based on the properties "LatestVersion" and "CurrentVersion"

what does everyone think of this approach?

next todo

  1. If event is an old version publish an 'UpdateMYEVENT' Event

thanks

like image 795
nesh_s Avatar asked Dec 06 '22 07:12

nesh_s


2 Answers

usually you only need to version the events, you can ignore the commands since you don't store them in the event store.

There are few ways to implement versioning.. my method is quite 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 conversion of events from the old one to the new one as you read the events from the event store.

also, you need to be aware that you never remove any old event classes, hence why I decorate them as Obsolete, to let other developers know not to use the event.

like image 165
Sarmaad Avatar answered Dec 11 '22 12:12

Sarmaad


If you are only adding & removing properties, there might be no need to version events; just ignore the serialized properties that are removed, and use sensible defaults for the ones you add.

like image 39
Tom Avatar answered Dec 11 '22 10:12

Tom