Alveus.EventBus.Memory
1.1.0
dotnet add package Alveus.EventBus.Memory --version 1.1.0
NuGet\Install-Package Alveus.EventBus.Memory -Version 1.1.0
<PackageReference Include="Alveus.EventBus.Memory" Version="1.1.0" />
<PackageVersion Include="Alveus.EventBus.Memory" Version="1.1.0" />
<PackageReference Include="Alveus.EventBus.Memory" />
paket add Alveus.EventBus.Memory --version 1.1.0
#r "nuget: Alveus.EventBus.Memory, 1.1.0"
#:package Alveus.EventBus.Memory@1.1.0
#addin nuget:?package=Alveus.EventBus.Memory&version=1.1.0
#tool nuget:?package=Alveus.EventBus.Memory&version=1.1.0
Alveus.EventBus
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.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Alveus.EventBus (>= 1.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.