Snapshots


What will happen when an aggregate has a lot of events? Would it not be an inefficient approach to read every event from an event stream and replay them in order to acquire the current state? To tackle this challenge, Snapshots offer an effective method. The Crystal Sharp framework offers seamless support for creating snapshots, making the implementation of snapshots within the framework a straightforward process.

Following is the code for an aggregate without snapshots:

“Order.cs” class:

public class Order : AggregateRoot<int>
{
    public string OrderCode { get; private set; }
    public decimal TotalPrice { get; private set; }

    // Rest of the code.
}

To enable snapshots on the aggregate above, the following steps are required:

  • Implementation of an aggregate’s snapshot class and decorating it with the Snapshot attribute with snapshot name and frequency.
  • Aggregate’s snapshot class must inherit from the SnapshotEntity<TKey> class.
  • Aggregate’s snapshot class must have public getters and setters for aggregate’s properties.
  • Aggregate’s class must inherit from the SnapshotAggregateRoot class.

The following code snippets present an illustration of how to perform the above steps:

“OrderSnapshot.cs” class:

[Snapshot("OrderSnapshot", 3)]
public class OrderSnapshot : SnapshotEntity<int>
{
    public string OrderCode { get; set; }
    public decimal TotalPrice { get; set; }
}

“Order.cs” class:

public class Order : SnapshotAggregateRoot<int, OrderSnapshot>
{
    public string OrderCode { get; private set; }
    public decimal TotalPrice { get; private set; }

    // Rest of the code.
}

In the above code snippets, the attribute [Snapshot("OrderSnapshot", 3)] requires two parameters: the name of the snapshot and frequency. As depicted in the code example, the frequency is defined as 3 implying that a snapshot will be generated after every three events.