Skip to content

Event Pipelines samples

Compare
Choose a tag to compare
@oskardudycz oskardudycz released this 25 Nov 08:37
· 521 commits to main since this release
25b6147

Event Pipelines

Shows how to compose event handlers in the processing pipelines to:

  • filter events,
  • transform them,
  • NOT requiring marker interfaces for events,
  • NOT requiring marker interfaces for handlers,
  • enables composition through regular functions,
  • allows using interfaces and classes if you want to,
  • can be used with Dependency Injection, but also without through builder,
  • integrates with MediatR if you want to.

Overview

Having UserAdded event:

public record UserAdded(
    string FirstName,
    string LastName,
    bool IsAdmin
);

We may want to create a pipeline, that will at first filter admin users:

public static bool IsAdmin(UserAdded @event) =>
    @event.IsAdmin;

Then map events to a dedicated AdminAdded event:

public record AdminAdded(
    string FirstName,
    string LastName
);

public static AdminAdded ToAdminAdded(UserAdded @event) =>
    new(@event.FirstName, @event.LastName);

Then handle mapped events storing information about new admins:

public static void Handle(AdminAdded @event) =>
    GlobalAdmins.Add(@event);

And distribute global admins to all tenants:

public static List<AdminGrantedInTenant> SendToTenants(UserAdded @event) =>
    TenantNames
        .Select(tenantName =>
            new AdminGrantedInTenant(@event.FirstName, @event.LastName, tenantName)
        )
        .ToList();

public record AdminGrantedInTenant(
    string FirstName,
    string LastName,
    string TenantName
);

public static void Handle(AdminGrantedInTenant @event) =>
    AdminsInTenants.Add(@event);
}

MediatR is great, but it doesn't enable such advanced pipelines. This sample shows how to construct event pipelines seamlessly. See EventBus implementation.

You can use it with Dependency Injection

serviceCollection
    .AddEventBus()
    .Filter<UserAdded>(AdminPipeline.IsAdmin)
    .Transform<UserAdded, AdminAdded>(AdminPipeline.ToAdminAdded)
    .Handle<AdminAdded>(AdminPipeline.Handle)
    .Transform<UserAdded, List<AdminGrantedInTenant>>(AdminPipeline.SendToTenants)
    .Handle<AdminGrantedInTenant>(AdminPipeline.Handle);

or without:

var builder = EventHandlersBuilder
    .Setup()
    .Filter<UserAdded>(AdminPipeline.IsAdmin)
    .Transform<UserAdded, AdminAdded>(AdminPipeline.ToAdminAdded)
    .Handle<AdminAdded>(AdminPipeline.Handle)
    .Transform<UserAdded, List<AdminGrantedInTenant>>(AdminPipeline.SendToTenants)
    .Handle<AdminGrantedInTenant>(AdminPipeline.Handle);

var eventBus = new EventBus(builder);

Samples

Check different ways of defining and integrating Event Handlers:

And how to integrate with MediatR: