Indiko.Blocks.EventBus.Abstractions
2.1.1
dotnet add package Indiko.Blocks.EventBus.Abstractions --version 2.1.1
NuGet\Install-Package Indiko.Blocks.EventBus.Abstractions -Version 2.1.1
<PackageReference Include="Indiko.Blocks.EventBus.Abstractions" Version="2.1.1" />
<PackageVersion Include="Indiko.Blocks.EventBus.Abstractions" Version="2.1.1" />
<PackageReference Include="Indiko.Blocks.EventBus.Abstractions" />
paket add Indiko.Blocks.EventBus.Abstractions --version 2.1.1
#r "nuget: Indiko.Blocks.EventBus.Abstractions, 2.1.1"
#:package Indiko.Blocks.EventBus.Abstractions@2.1.1
#addin nuget:?package=Indiko.Blocks.EventBus.Abstractions&version=2.1.1
#tool nuget:?package=Indiko.Blocks.EventBus.Abstractions&version=2.1.1
Indiko.Blocks.EventBus.Abstractions
Core abstractions for event-driven architecture and publish-subscribe messaging in the Indiko framework.
Overview
This package defines the fundamental contracts for implementing event bus systems, enabling decoupled communication between application components through asynchronous event publishing and handling.
Features
- IEventBus Interface: Core contract for event bus implementations
- IEvent Interface: Marker interface for event messages
- IEventHandler<TEvent>: Generic event handler interface
- Event Registration: Dynamic event handler registration
- Publish-Subscribe Pattern: Decoupled event-driven communication
- Async/Await Support: Full asynchronous event handling
- Multiple Handlers: Support for multiple handlers per event type
- Builder Pattern: Fluent API for event bus configuration
Installation
dotnet add package Indiko.Blocks.EventBus.Abstractions
Key Interfaces
IEventBus
Main interface for event bus operations.
public interface IEventBus
{
// Connection management
Task<bool> ConnectAsync(CancellationToken cancellationToken = default);
Task DisconnectAsync(CancellationToken cancellationToken = default);
// Publish events
void Publish<TEvent>(TEvent eventMessage) where TEvent : IEvent;
ValueTask PublishAsync<TEvent>(TEvent @event, CancellationToken cancellationToken = default)
where TEvent : IEvent;
// Handler registration
void RegisterEventHandler<TEvent>(IEventHandler<TEvent> eventHandler)
where TEvent : IEvent;
void RegisterEventHandlers<TEvent>(params IEventHandler<TEvent>[] eventHandlers)
where TEvent : IEvent;
void UnRegisterEventHandler<TEvent>() where TEvent : IEvent;
void UnRegisterAllEventHandlers();
}
IEvent
Marker interface for event messages.
public interface IEvent
{
// Marker interface - events inherit from this
}
IEventHandler<TEvent>
Interface for handling specific event types.
public interface IEventHandler<TEvent> where TEvent : IEvent
{
Task HandleAsync(TEvent @event, CancellationToken cancellationToken = default);
}
Usage Examples
Define Events
using Indiko.Blocks.EventBus.Abstractions.Interfaces;
// Simple event
public class UserCreatedEvent : IEvent
{
public Guid UserId { get; set; }
public string Email { get; set; }
public DateTime CreatedAt { get; set; }
}
// Event with rich data
public class OrderPlacedEvent : IEvent
{
public Guid OrderId { get; set; }
public Guid UserId { get; set; }
public List<OrderItem> Items { get; set; }
public decimal TotalAmount { get; set; }
public DateTime OrderDate { get; set; }
}
public class OrderItem
{
public Guid ProductId { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
}
Implement Event Handlers
// Single event handler
public class SendWelcomeEmailHandler : IEventHandler<UserCreatedEvent>
{
private readonly IEmailService _emailService;
public SendWelcomeEmailHandler(IEmailService emailService)
{
_emailService = emailService;
}
public async Task HandleAsync(UserCreatedEvent @event, CancellationToken cancellationToken = default)
{
await _emailService.SendWelcomeEmailAsync(@event.Email, cancellationToken);
}
}
// Another handler for the same event
public class CreateUserProfileHandler : IEventHandler<UserCreatedEvent>
{
private readonly IProfileService _profileService;
public CreateUserProfileHandler(IProfileService profileService)
{
_profileService = profileService;
}
public async Task HandleAsync(UserCreatedEvent @event, CancellationToken cancellationToken = default)
{
await _profileService.CreateDefaultProfileAsync(@event.UserId, cancellationToken);
}
}
Register Handlers
public class Startup : WebStartup
{
public override void ConfigureServices(IServiceCollection services)
{
base.ConfigureServices(services);
// Register event handlers
services.AddScoped<IEventHandler<UserCreatedEvent>, SendWelcomeEmailHandler>();
services.AddScoped<IEventHandler<UserCreatedEvent>, CreateUserProfileHandler>();
services.AddScoped<IEventHandler<OrderPlacedEvent>, ProcessOrderHandler>();
}
}
Publish Events
public class UserService
{
private readonly IEventBus _eventBus;
private readonly IUserRepository _userRepository;
public UserService(IEventBus eventBus, IUserRepository userRepository)
{
_eventBus = eventBus;
_userRepository = userRepository;
}
public async Task<User> CreateUserAsync(string email, string password)
{
var user = new User
{
Id = Guid.NewGuid(),
Email = email,
CreatedAt = DateTime.UtcNow
};
await _userRepository.AddAsync(user);
// Publish event - all registered handlers will be invoked
await _eventBus.PublishAsync(new UserCreatedEvent
{
UserId = user.Id,
Email = user.Email,
CreatedAt = user.CreatedAt
});
return user;
}
}
Event Handler Patterns
Fire and Forget
public class AuditLogHandler : IEventHandler<UserCreatedEvent>
{
private readonly IAuditService _auditService;
public async Task HandleAsync(UserCreatedEvent @event, CancellationToken cancellationToken = default)
{
// Non-critical operation - log and continue
try
{
await _auditService.LogUserCreationAsync(@event.UserId);
}
catch (Exception ex)
{
// Log error but don't throw
Console.WriteLine($"Audit logging failed: {ex.Message}");
}
}
}
Critical Handler with Retry
public class SendOrderConfirmationHandler : IEventHandler<OrderPlacedEvent>
{
private readonly IEmailService _emailService;
private readonly ILogger<SendOrderConfirmationHandler> _logger;
public async Task HandleAsync(OrderPlacedEvent @event, CancellationToken cancellationToken = default)
{
int maxRetries = 3;
for (int attempt = 0; attempt < maxRetries; attempt++)
{
try
{
await _emailService.SendOrderConfirmationAsync(@event, cancellationToken);
return; // Success
}
catch (Exception ex)
{
_logger.LogWarning($"Attempt {attempt + 1} failed: {ex.Message}");
if (attempt == maxRetries - 1)
throw; // Final attempt failed
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)), cancellationToken);
}
}
}
}
Conditional Handler
public class PremiumUserBonusHandler : IEventHandler<OrderPlacedEvent>
{
private readonly IUserService _userService;
private readonly IRewardService _rewardService;
public async Task HandleAsync(OrderPlacedEvent @event, CancellationToken cancellationToken = default)
{
var user = await _userService.GetUserAsync(@event.UserId);
// Only process for premium users
if (user.IsPremium && @event.TotalAmount >= 100)
{
await _rewardService.AddBonusPointsAsync(@event.UserId, @event.TotalAmount * 0.1m);
}
}
}
Builder Pattern
EventBusBuilder
Fluent API for configuring event bus.
public class EventBusBuilder : IEventBusBuilder
{
public IEventBusBuilder AddHandler<TEvent, THandler>()
where TEvent : IEvent
where THandler : IEventHandler<TEvent>;
public IEventBusBuilder Configure(Action<EventBusOptions> options);
public IEventBus Build();
}
Usage
var eventBus = new EventBusBuilder()
.AddHandler<UserCreatedEvent, SendWelcomeEmailHandler>()
.AddHandler<UserCreatedEvent, CreateUserProfileHandler>()
.AddHandler<OrderPlacedEvent, ProcessOrderHandler>()
.Configure(options =>
{
options.MaxConcurrentHandlers = 10;
options.EnableRetry = true;
})
.Build();
Best Practices
- Keep Events Immutable: Use read-only properties
- Event Naming: Use past tense (UserCreated, OrderPlaced, PaymentProcessed)
- Handler Independence: Handlers should not depend on execution order
- Error Handling: Always handle exceptions in handlers
- Idempotency: Design handlers to be idempotent
- Single Responsibility: One handler, one responsibility
- Event Versioning: Plan for event schema evolution
Event Patterns
Domain Events
public abstract class DomainEvent : IEvent
{
public Guid EventId { get; } = Guid.NewGuid();
public DateTime OccurredAt { get; } = DateTime.UtcNow;
public string EventType => GetType().Name;
}
public class ProductStockChangedEvent : DomainEvent
{
public Guid ProductId { get; set; }
public int OldQuantity { get; set; }
public int NewQuantity { get; set; }
public string Reason { get; set; }
}
Integration Events
public abstract class IntegrationEvent : IEvent
{
public Guid Id { get; set; } = Guid.NewGuid();
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public string CorrelationId { get; set; }
}
public class PaymentCompletedEvent : IntegrationEvent
{
public Guid OrderId { get; set; }
public decimal Amount { get; set; }
public string TransactionId { get; set; }
}
Configuration Options
EventBusOptions
public class EventBusOptions
{
public int MaxConcurrentHandlers { get; set; } = 10;
public bool EnableRetry { get; set; } = true;
public int MaxRetryAttempts { get; set; } = 3;
public TimeSpan RetryDelay { get; set; } = TimeSpan.FromSeconds(1);
public bool ThrowOnHandlerError { get; set; } = false;
}
Target Framework
- .NET 10
Dependencies
Indiko.Blocks.Common.Abstractions
License
See LICENSE file in the repository root.
Related Packages
Indiko.Blocks.EventBus.InMemory- In-memory event bus implementationIndiko.Blocks.EventBus.RabbitMQ- RabbitMQ-based event busIndiko.Blocks.Mediation.Abstractions- CQRS and mediator patternIndiko.Blocks.Common.Management- Block management system
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Indiko.Blocks.Common.Abstractions (>= 2.1.1)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Indiko.Blocks.EventBus.Abstractions:
| Package | Downloads |
|---|---|
|
Indiko.Blocks.EventBus.RabbitMQ
Building Blocks EventBus RabbitMQ |
|
|
Indiko.Blocks.EventBus.InMemory
Building Blocks EventBus InMemory |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.1.1 | 49 | 12/2/2025 |
| 2.1.0 | 53 | 12/2/2025 |
| 2.0.0 | 314 | 9/17/2025 |
| 1.7.23 | 189 | 9/8/2025 |
| 1.7.22 | 176 | 9/8/2025 |
| 1.7.21 | 176 | 8/14/2025 |
| 1.7.20 | 211 | 6/23/2025 |
| 1.7.19 | 195 | 6/3/2025 |
| 1.7.18 | 200 | 5/29/2025 |
| 1.7.17 | 198 | 5/26/2025 |
| 1.7.15 | 143 | 4/12/2025 |
| 1.7.14 | 164 | 4/11/2025 |
| 1.7.13 | 152 | 3/29/2025 |
| 1.7.12 | 166 | 3/28/2025 |
| 1.7.11 | 181 | 3/28/2025 |
| 1.7.10 | 167 | 3/28/2025 |
| 1.7.9 | 168 | 3/28/2025 |
| 1.7.8 | 181 | 3/28/2025 |
| 1.7.5 | 207 | 3/17/2025 |
| 1.7.4 | 179 | 3/16/2025 |
| 1.7.3 | 183 | 3/16/2025 |
| 1.7.2 | 196 | 3/16/2025 |
| 1.7.1 | 206 | 3/11/2025 |
| 1.6.8 | 232 | 3/11/2025 |
| 1.6.7 | 265 | 3/4/2025 |
| 1.6.6 | 164 | 2/26/2025 |
| 1.6.5 | 168 | 2/20/2025 |
| 1.6.4 | 163 | 2/20/2025 |
| 1.6.3 | 153 | 2/5/2025 |
| 1.6.2 | 147 | 1/24/2025 |
| 1.6.1 | 152 | 1/24/2025 |
| 1.6.0 | 142 | 1/16/2025 |
| 1.5.2 | 143 | 1/16/2025 |
| 1.5.1 | 182 | 11/3/2024 |
| 1.5.0 | 167 | 10/26/2024 |
| 1.3.2 | 185 | 10/24/2024 |
| 1.3.0 | 193 | 10/10/2024 |
| 1.2.5 | 167 | 10/9/2024 |
| 1.2.4 | 171 | 10/8/2024 |
| 1.2.1 | 153 | 10/3/2024 |
| 1.2.0 | 178 | 9/29/2024 |
| 1.1.1 | 169 | 9/23/2024 |
| 1.1.0 | 180 | 9/18/2024 |
| 1.0.33 | 176 | 9/15/2024 |
| 1.0.28 | 166 | 8/28/2024 |
| 1.0.27 | 199 | 8/24/2024 |
| 1.0.26 | 176 | 7/7/2024 |
| 1.0.25 | 193 | 7/6/2024 |
| 1.0.24 | 141 | 6/25/2024 |
| 1.0.23 | 161 | 6/1/2024 |
| 1.0.22 | 145 | 5/14/2024 |
| 1.0.21 | 128 | 5/14/2024 |
| 1.0.20 | 168 | 4/8/2024 |
| 1.0.19 | 164 | 4/3/2024 |
| 1.0.18 | 186 | 3/23/2024 |
| 1.0.17 | 202 | 3/19/2024 |
| 1.0.16 | 177 | 3/19/2024 |
| 1.0.15 | 196 | 3/11/2024 |
| 1.0.14 | 187 | 3/10/2024 |
| 1.0.13 | 182 | 3/6/2024 |
| 1.0.12 | 184 | 3/1/2024 |
| 1.0.11 | 180 | 3/1/2024 |
| 1.0.10 | 179 | 3/1/2024 |
| 1.0.9 | 207 | 3/1/2024 |
| 1.0.8 | 196 | 2/19/2024 |
| 1.0.7 | 192 | 2/17/2024 |
| 1.0.6 | 180 | 2/17/2024 |
| 1.0.5 | 156 | 2/17/2024 |
| 1.0.4 | 191 | 2/7/2024 |
| 1.0.3 | 163 | 2/6/2024 |
| 1.0.1 | 147 | 2/6/2024 |
| 1.0.0 | 214 | 1/9/2024 |
| 1.0.0-preview99 | 213 | 12/22/2023 |
| 1.0.0-preview98 | 166 | 12/21/2023 |
| 1.0.0-preview97 | 170 | 12/21/2023 |
| 1.0.0-preview96 | 180 | 12/20/2023 |
| 1.0.0-preview94 | 171 | 12/18/2023 |
| 1.0.0-preview93 | 353 | 12/13/2023 |
| 1.0.0-preview92 | 165 | 12/13/2023 |
| 1.0.0-preview91 | 192 | 12/12/2023 |
| 1.0.0-preview90 | 162 | 12/11/2023 |
| 1.0.0-preview89 | 152 | 12/11/2023 |
| 1.0.0-preview88 | 237 | 12/6/2023 |
| 1.0.0-preview87 | 170 | 12/6/2023 |
| 1.0.0-preview86 | 168 | 12/6/2023 |
| 1.0.0-preview85 | 187 | 12/6/2023 |
| 1.0.0-preview84 | 168 | 12/5/2023 |
| 1.0.0-preview83 | 198 | 12/5/2023 |
| 1.0.0-preview82 | 193 | 12/5/2023 |
| 1.0.0-preview81 | 168 | 12/4/2023 |
| 1.0.0-preview80 | 155 | 12/1/2023 |
| 1.0.0-preview77 | 173 | 12/1/2023 |
| 1.0.0-preview76 | 181 | 12/1/2023 |
| 1.0.0-preview75 | 160 | 12/1/2023 |
| 1.0.0-preview74 | 194 | 11/26/2023 |
| 1.0.0-preview73 | 190 | 11/7/2023 |
| 1.0.0-preview72 | 176 | 11/6/2023 |
| 1.0.0-preview71 | 153 | 11/3/2023 |
| 1.0.0-preview70 | 171 | 11/2/2023 |
| 1.0.0-preview69 | 176 | 11/2/2023 |
| 1.0.0-preview68 | 171 | 11/2/2023 |
| 1.0.0-preview67 | 180 | 11/2/2023 |
| 1.0.0-preview66 | 128 | 11/2/2023 |
| 1.0.0-preview65 | 161 | 11/2/2023 |
| 1.0.0-preview64 | 178 | 11/2/2023 |
| 1.0.0-preview63 | 179 | 11/2/2023 |
| 1.0.0-preview62 | 167 | 11/1/2023 |
| 1.0.0-preview61 | 163 | 11/1/2023 |
| 1.0.0-preview60 | 169 | 11/1/2023 |
| 1.0.0-preview59 | 156 | 11/1/2023 |
| 1.0.0-preview58 | 175 | 10/31/2023 |
| 1.0.0-preview57 | 167 | 10/31/2023 |
| 1.0.0-preview56 | 176 | 10/31/2023 |
| 1.0.0-preview55 | 163 | 10/31/2023 |
| 1.0.0-preview54 | 183 | 10/31/2023 |
| 1.0.0-preview53 | 153 | 10/31/2023 |
| 1.0.0-preview52 | 158 | 10/31/2023 |
| 1.0.0-preview51 | 161 | 10/31/2023 |
| 1.0.0-preview50 | 174 | 10/31/2023 |
| 1.0.0-preview48 | 158 | 10/31/2023 |
| 1.0.0-preview46 | 169 | 10/31/2023 |
| 1.0.0-preview45 | 177 | 10/31/2023 |
| 1.0.0-preview44 | 166 | 10/31/2023 |
| 1.0.0-preview43 | 172 | 10/31/2023 |
| 1.0.0-preview42 | 181 | 10/30/2023 |
| 1.0.0-preview41 | 171 | 10/30/2023 |
| 1.0.0-preview40 | 195 | 10/27/2023 |
| 1.0.0-preview39 | 178 | 10/27/2023 |
| 1.0.0-preview38 | 188 | 10/27/2023 |
| 1.0.0-preview37 | 187 | 10/27/2023 |
| 1.0.0-preview36 | 169 | 10/27/2023 |
| 1.0.0-preview35 | 175 | 10/27/2023 |
| 1.0.0-preview34 | 155 | 10/27/2023 |
| 1.0.0-preview33 | 183 | 10/26/2023 |
| 1.0.0-preview32 | 185 | 10/26/2023 |
| 1.0.0-preview31 | 190 | 10/26/2023 |
| 1.0.0-preview30 | 171 | 10/26/2023 |
| 1.0.0-preview29 | 174 | 10/26/2023 |
| 1.0.0-preview28 | 177 | 10/26/2023 |
| 1.0.0-preview27 | 180 | 10/26/2023 |
| 1.0.0-preview26 | 154 | 10/25/2023 |
| 1.0.0-preview25 | 160 | 10/23/2023 |
| 1.0.0-preview24 | 185 | 10/23/2023 |
| 1.0.0-preview23 | 168 | 10/23/2023 |
| 1.0.0-preview22 | 162 | 10/23/2023 |
| 1.0.0-preview21 | 167 | 10/23/2023 |
| 1.0.0-preview20 | 158 | 10/20/2023 |
| 1.0.0-preview19 | 183 | 10/19/2023 |
| 1.0.0-preview18 | 182 | 10/18/2023 |
| 1.0.0-preview16 | 158 | 10/11/2023 |
| 1.0.0-preview14 | 185 | 10/10/2023 |
| 1.0.0-preview13 | 178 | 10/10/2023 |
| 1.0.0-preview12 | 180 | 10/9/2023 |
| 1.0.0-preview101 | 155 | 1/5/2024 |