Alveus.EventBus (1.1.0)

Published 2025-07-06 08:26:11 +02:00 by mike

Installation

dotnet nuget add source --name public --username your_username --password your_token 
dotnet add package --source public --version 1.1.0 Alveus.EventBus

About this package

Provides a decoupled event bus for in-process communication.

Alveus.EventBus

Release Build status

Alveus.EventBus is a lightweight, in-process library for enabling decoupled communication between different parts of an application using a publish-subscribe pattern. This promotes cleaner, more maintainable code by allowing components to interact without having direct dependencies on each other.

This repository contains two packages:

  • Alveus.EventBus: The core interfaces.
  • Alveus.EventBus.Memory: A simple, thread-safe in-memory implementation.

Features

  • Simple API: Easy to subscribe to and publish events.
  • Decoupled Components: Publishers and subscribers don't need to know about each other.
  • Multiple Handler Types: Supports synchronous (Action<T>), asynchronous (Func<T, Task>), and cancellable ( Func<T, CancellationToken, Task>) handlers.
  • Thread-Safe: The MemoryEventBus implementation is thread-safe for concurrent access.

Basic Usage

Here’s a complete example demonstrating how to define, subscribe to, and publish events.

1. Define an Event

An event can be any plain C# class (POCO) that holds the data you want to pass.

// Define an event that will be published when a user logs in.
public class UserLoggedInEvent
{
    public string Username { get; }
    public DateTime LoginTime { get; }

    public UserLoggedInEvent(string username, DateTime loginTime)
    {
        Username = username;
        LoginTime = loginTime;
    }
}

2. Create Event Handlers

Handlers are methods that will be executed when an event is published. You can create both synchronous and asynchronous handlers.

// A synchronous handler that logs the event to the console.
public void OnUserLoggedIn(UserLoggedInEvent @event)
{
    Console.WriteLine($"[Sync Handler] User '{@event.Username}' logged in at {@event.LoginTime:HH:mm:ss}.");
}

// An asynchronous handler that might perform a longer-running task, like sending an email.
public async Task OnUserLoggedInAsync(UserLoggedInEvent @event)
{
    Console.WriteLine($"[Async Handler] Welcome email process for '{@event.Username}' started...");
    await Task.Delay(1000); // Simulate sending an email
    Console.WriteLine($"[Async Handler] Welcome email for '{@event.Username}' sent.");
}

// A cancellable asynchronous handler that supports cancellation.
public async Task OnUserLoggedInWithCancellationAsync(UserLoggedInEvent @event, CancellationToken cancellationToken)
{
    Console.WriteLine($"[Cancellable Handler] Processing login for '{@event.Username}'...");
    await Task.Delay(1000, cancellationToken); // Cancellable operation
    Console.WriteLine($"[Cancellable Handler] Login processed for '{@event.Username}'.");
}

3. Subscribe and Publish

using Alveus.EventBus;
using Alveus.EventBus.Memory;
using System;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main(string[] args)
    {
        // 1. Create an instance of the event bus.
        // IEventBus is often registered as a singleton in a DI container.
        IEventBus eventBus = new MemoryEventBus();
        
        // Create an instance of our class containing the handlers
        var handlers = new MyEventHandlers();

        // 2. Subscribe the handlers.
        eventBus.Subscribe<UserLoggedInEvent>(handlers.OnUserLoggedIn);
        eventBus.Subscribe<UserLoggedInEvent>(handlers.OnUserLoggedInAsync);
        eventBus.Subscribe<UserLoggedInEvent>(handlers.OnUserLoggedInWithCancellationAsync);

        // 3. Create an instance of the event.
        var loginEvent = new UserLoggedInEvent("Alice", DateTime.UtcNow);

        // 4. Publish the event asynchronously.
        // PublishAsync will invoke both sync and async handlers and await the async ones.
        Console.WriteLine("Publishing UserLoggedInEvent...");
        await eventBus.PublishAsync(loginEvent);
        Console.WriteLine("All handlers have completed.");
    }
}

public class MyEventHandlers
{
    // A synchronous handler.
    public void OnUserLoggedIn(UserLoggedInEvent @event)
    {
        Console.WriteLine($"[Sync Handler] User '{@event.Username}' logged in at {@event.LoginTime:HH:mm:ss}.");
    }

    // An asynchronous handler.
    public async Task OnUserLoggedInAsync(UserLoggedInEvent @event)
    {
        Console.WriteLine($"[Async Handler] Welcome email process for '{@event.Username}' started...");
        await Task.Delay(1000); // Simulate sending an email.
        Console.WriteLine($"[Async Handler] Welcome email for '{@event.Username}' sent.");
    }
}

Output of the Example:

Publishing UserLoggedInEvent...
[Sync Handler] User 'Alice' logged in at 14:30:00.
[Async Handler] Welcome email process for 'Alice' started...
[Async Handler] Welcome email for 'Alice' sent.
All handlers have completed.

Note

When publishing events synchronously with Alveus.EventBus.Memory using void Publish<TEventType>(TEventType @event), asynchronous handlers will not be called. This is to prevent the situation where handlers get called either as Fire or Forget, or in a way that blocks execution, introducing the risk of deadlocks.

License

This project is licensed under the MIT License. See the LICENSE.md file for details.

Details
NuGet
2025-07-06 08:26:11 +02:00
10
Alveus Dev (https://alveus.dev)
23 KiB
Assets (4)
Versions (2) View all
1.1.0 2025-07-06
1.0.0 2025-07-05