Event Upgrading
Also sometimes known as event upcasting. At some point you might find the need to replace a event with zero or more events. Some use cases might be:
- A previous application version introduced a domain error in the form of a wrong event being emitted from the aggregate.
- The domain has changed, either from a change in requirements or simply from a better understanding of the domain.
In the above cases, Akkatecture suggests that you implement an AggregateEventUpcaster<,> and then you can add your own upcast implementation by implementing IUpcast<,> on the upcaster. Lets do this with an example.
Imagine we have an OrderAggregate that emits ProductAddedEvents, due to new domain improvements or required it has been deemed necessary to have a new version of that event called ProductAddedEventV2. We make changes to the aggregate to emit the new version of the event, but we have a problem in that the old event is persisted in the event journal. To remedy this we will implement a suitable AggregateEventUpcaster<,>.
public class OrderAggregateEventUpcaster : AggregateEventUpcaster<OrderAggregate, OrderId>,IUpcast<ProductAddedEvent, ProductAddedEventV2>{public ProductAddedEventV2 Upcast(ProductAddedEvent aggregateEvent){return new ProductAddedEventV2(aggregateEvent.AggregateId,/* other things to enrich the event */string.Empty);}}
and then our read journal hocon configuration requires the following to be added to it
akka.persistence {journal {plugin = ""akka.persistence.journal.some-plugin""some-plugin {event-adapters {##fully qualified class name and assembly of the upcasteraggregate-event-upcaster = ""YourDomain.OrderAggregateEventUpcaster, YourDomain""}event-adapter-bindings = {""Akkatecture.Aggregates.ICommittedEvent, Akkatecture"" = aggregate-event-upcaster}}}}
Now in our order aggrege state, we only need to implement the apply method of the new aggregate event
public class OrderState : AggregateState<OrderState, OrderId>,IApply<ProductAddedEventV2>,IApply<ProductRemovedEvent>,{public Products Products { get; private set; }public void Apply(ProductRemovedEvent aggregateEvent){Products.Remove(aggregateEvent.Product);}public void Apply(ProductAddedEventV2 aggregateEvent){Products.Add(aggregateEvent.Product);}}
The event upcaster works as a normal
IReadEventAdapterfrom akka.net.