Domain events as objects

Bringing domain events to code is easy. Each event is an object. It means that we can represent event types as classes or structs. Since we will need to serialize events later and structs aren't playing nicely with serializers, we will implement domain events as classes.

We have the following basic operations on our ClassifiedAd entity:

  • Create a new classified ad
  • Set the ad title
  • Update text
  • Update price
  • Publish the ad (send for review)

Each of those operations changes the state of our entity and by doing this raises an imaginary domain event. We have all those events on our sticky notes:

Classes that represent events need to clearly describe events (what happened) and contain the necessary information that explains how the system state has changed. Usually, events are reactions to executions of commands. Therefore, data in events typically represent data in commands and maybe some other details from the entity from which the event has been raised.

Let's create some domain event classes now. Bear in mind that this is our first ever implementation of domain events, and if you were reading about things like event-sourcing, you might find it oversimplified, but this is intentional.

using System;

namespace Marketplace.Domain
{
public static class Events
{
public class ClassifiedAdCreated
{
public Guid Id { get; set; }
public Guid OwnerId { get; set; }
}

public class ClassifiedAdTitleChanged
{
public Guid Id { get; set; }
public string Title { get; set; }
}

public class ClassifiedAdTextUpdated
{
public Guid Id { get; set; }
public string AdText { get; set; }
}

public class ClassifiedAdPriceUpdated
{
public Guid Id { get; set; }
public decimal Price { get; set; }
public string CurrencyCode { get; set; }
}

public class ClassidiedAdSentForReview
{
public Guid Id { get; set; }
}
}
}

Event classes are wrapped inside the Events static class, which gives us some namespace. Hence also that all properties in these classes are of primitive types. We do not use value objects in events. It is a significant thing to remember. The reason for only using primitive types in events is because domain events, as mentioned before, often used across systems. Events can be seen as our system published contract. If we use event-sourcing and events are being persisted, we also cannot tolerate a situation, when the rules in some value object have changed, and we cannot load our event anymore because the data for the value object is now considered to be invalid. Of course, not using value objects in events lead that some more complex value objects need to be flattered. In our case, we extract values from the Price property to two properties of the ClassifiedAdPriceUpdated - Price, which represents the amount, and CurrencyCode.

You can see that each event has the Id property because it makes no sense to raise an event without knowing which entity comes from. So, each operation needs to take care that the entity id is populated in the events that it raises.

Again, the most critical thing about domain events is that represent things that happened, and these things cannot be changed, because we have no time machine or Tardis to erase or fix the past. Therefore, events should be as simple as possible so we can always load past events and this should never fail.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.98.207