Skip to content

Source Generation

EventFlow provides source generators to reduce boilerplate code when working with aggregates. This makes your code cleaner and easier to maintain.

How to use

Add EventFlow.SourceGenerators package.

1
dotnet add package EventFlow.SourceGenerators

Add the AggregateExtensions attribute to your aggregate class. The C# compiler will automatically generate the necessary source code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
using EventFlow.SourceGenerators;

[AggregateExtensions]
public class OrderAggregate(OrderAggregateId id) :
    AggregateRoot<OrderAggregate, OrderAggregateId>(id)
{
    public Task DoSomething()
    {
        // Business logic here
    }
}

public class OrderAggregateId(string value) : Identity<OrderAggregateId>(value);

How it helps

Without source generators, you must specify the aggregate type and identity type explicitly in multiple places.

  1. Event declaration.

    1
    2
    public class OrderCreated : 
        IAggregateEvent<OrderAggregate, OrderAggregateId>
    
  2. Subscriber declaration.

    1
    2
    public class OrderAggregateSubscribers :
        ISubscribeSynchronousTo<OrderAggregate, OrderAggregateId, OrderCreated>
    
  3. Usage of IAggregateStore.

    1
    2
    3
    4
    5
    await aggregateStore.UpdateAsync<OrderAggregate, OrderAggregateId>(
        id,
        SourceId.New,
        (order, _) => order.DoSomething(),
        cancellationToken);
    
  4. Usage of IEventStore.

    1
    2
    var events = await eventStore.LoadEventsAsync<OrderAggregate, OrderAggregateId>(
        id, cancellationToken);
    

Using source generators simplifies the code by omitting the aggregate and identity types.

  1. Event declaration.

    1
    public class OrderCreated : OrderAggregateEvent
    
  2. Subscriber declaration.

    1
    2
    public class OrderAggregateSubscribers :
        ISubscribeSynchronousTo<OrderCreated>
    
  3. Usage of IAggregateStore.

    1
    2
    3
    4
    await aggregateStore.UpdateAsync(
        id,
        order => order.DoSomething(),
        cancellationToken);
    
  4. Usage of IEventStore.

    1
    var events = await eventStore.LoadEventsAsync(id, cancellationToken);