eBuildingBlocks.EventBus 2.0.0

dotnet add package eBuildingBlocks.EventBus --version 2.0.0
                    
NuGet\Install-Package eBuildingBlocks.EventBus -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="eBuildingBlocks.EventBus" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="eBuildingBlocks.EventBus" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="eBuildingBlocks.EventBus" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add eBuildingBlocks.EventBus --version 2.0.0
                    
#r "nuget: eBuildingBlocks.EventBus, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package eBuildingBlocks.EventBus@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=eBuildingBlocks.EventBus&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=eBuildingBlocks.EventBus&version=2.0.0
                    
Install as a Cake Tool

eBuildingBlocks.EventBus

A comprehensive event-driven architecture building block for .NET applications that provides event publishing, subscription, and integration capabilities using MassTransit and RabbitMQ.

Overview

eBuildingBlocks.EventBus is a foundational library that implements event-driven architecture patterns and provides event publishing, subscription, and integration capabilities. It leverages MassTransit and RabbitMQ to provide a robust, scalable event bus solution for microservices and distributed applications.

Key Features

📡 Event Publishing

  • Event Publisher: Centralized event publishing interface
  • MassTransit Integration: Built-in MassTransit support
  • RabbitMQ Support: Reliable message queuing with RabbitMQ
  • Event Contracts: Standardized event contract definitions

📨 Event Subscription

  • Event Subscriber: Event subscription and handling
  • Message Consumers: MassTransit consumer implementations
  • Event Handlers: Centralized event handling logic
  • Integration Events: Cross-service communication events

🔄 Event Types & Contracts

  • Integration Events: Cross-service communication
  • Domain Events: Domain-specific event types
  • Event Type Enum: Categorized event types
  • Event Contracts: Standardized event structures

🛠️ Infrastructure

  • MassTransit Extensions: Configuration and setup utilities
  • RabbitMQ Configuration: Connection and queue management
  • Event Routing: Intelligent event routing and filtering
  • Error Handling: Robust error handling and retry mechanisms

Installation

dotnet add package eBuildingBlocks.EventBus

Quick Start

1. Configure Event Bus

using eBuildingBlocks.EventBus.Events;

// Configure MassTransit with RabbitMQ
services.AddMassTransit(x =>
{
    x.UsingRabbitMq((context, cfg) =>
    {
        cfg.Host("localhost", "/", h =>
        {
            h.Username("guest");
            h.Password("guest");
        });
        
        cfg.ConfigureEndpoints(context);
    });
});

2. Create Event Contracts

using eBuildingBlocks.EventBus.Contracts;

public class UserCreatedEvent : IntegrationEvent
{
    public Guid UserId { get; set; }
    public string Username { get; set; }
    public string Email { get; set; }
    public DateTime CreatedAt { get; set; }
}

3. Publish Events

using eBuildingBlocks.EventBus.Events;

public class UserService
{
    private readonly IEventPublisher _eventPublisher;
    
    public UserService(IEventPublisher eventPublisher)
    {
        _eventPublisher = eventPublisher;
    }
    
    public async Task<User> CreateUserAsync(CreateUserRequest request)
    {
        var user = new User
        {
            Id = Guid.NewGuid(),
            Username = request.Username,
            Email = request.Email
        };
        
        // Save user to database...
        
        // Publish event
        await _eventPublisher.PublishAsync(new UserCreatedEvent
        {
            UserId = user.Id,
            Username = user.Username,
            Email = user.Email,
            CreatedAt = DateTime.UtcNow
        });
        
        return user;
    }
}

4. Subscribe to Events

using eBuildingBlocks.EventBus.Events;

public class UserCreatedEventHandler : IEventSubscriber<UserCreatedEvent>
{
    private readonly IEmailService _emailService;
    
    public UserCreatedEventHandler(IEmailService emailService)
    {
        _emailService = emailService;
    }
    
    public async Task HandleAsync(UserCreatedEvent @event)
    {
        // Send welcome email
        await _emailService.SendWelcomeEmailAsync(@event.Email, @event.Username);
        
        // Additional processing...
    }
}

Features in Detail

Event Publisher Interface

Centralized event publishing interface:

public interface IEventPublisher
{
    Task PublishAsync<T>(T message, CancellationToken cancellationToken = default) where T : class;
    Task PublishAsync<T>(T message, IPipe<SendContext<T>> pipe, CancellationToken cancellationToken = default) where T : class;
}

Event Subscriber Interface

Event subscription and handling interface:

public interface IEventSubscriber<T> where T : class
{
    Task HandleAsync(T message);
}

Integration Events

Base class for integration events:

public abstract class IntegrationEvent
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public DateTime CreationDate { get; set; } = DateTime.UtcNow;
    public string Payload { get; set; } = string.Empty;
}

Event Types

Categorized event types for better organization:

public enum EventType
{
    UserCreated,
    UserUpdated,
    UserDeleted,
    OrderCreated,
    OrderConfirmed,
    OrderCancelled,
    PaymentProcessed,
    PaymentFailed
}

MassTransit Extensions

Configuration utilities for MassTransit:

public static class MassTransitExtensions
{
    public static void ConfigureRabbitMq(this IBusRegistrationConfigurator configurator, string host, string username, string password)
    {
        configurator.UsingRabbitMq((context, cfg) =>
        {
            cfg.Host(host, "/", h =>
            {
                h.Username(username);
                h.Password(password);
            });
            
            cfg.ConfigureEndpoints(context);
        });
    }
}

Project Structure

eBuildingBlocks.EventBus/
├── Contracts/
│   ├── IntegrationEvent.cs
│   ├── ITenantSubscriptionExpired.cs
│   └── IUserProjectAssigned.cs
├── Enums/
│   └── EventType.cs
├── Events/
│   ├── EventPublisher.cs
│   ├── EventSubscriber.cs
│   ├── IEventPublisher.cs
│   ├── IEventSubscriber.cs
│   └── MassTransitExtensions.cs
└── eBuildingBlocks.EventBus.csproj

Usage Examples

Publishing Events

public class OrderService
{
    private readonly IEventPublisher _eventPublisher;
    
    public async Task<Order> CreateOrderAsync(CreateOrderRequest request)
    {
        var order = new Order
        {
            Id = Guid.NewGuid(),
            CustomerId = request.CustomerId,
            TotalAmount = request.TotalAmount,
            Status = OrderStatus.Created
        };
        
        // Save order to database...
        
        // Publish order created event
        await _eventPublisher.PublishAsync(new OrderCreatedEvent
        {
            OrderId = order.Id,
            CustomerId = order.CustomerId,
            TotalAmount = order.TotalAmount,
            CreatedAt = DateTime.UtcNow
        });
        
        return order;
    }
    
    public async Task ConfirmOrderAsync(Guid orderId)
    {
        var order = await _orderRepository.GetByIdAsync(orderId);
        order.Status = OrderStatus.Confirmed;
        
        // Update order in database...
        
        // Publish order confirmed event
        await _eventPublisher.PublishAsync(new OrderConfirmedEvent
        {
            OrderId = order.Id,
            ConfirmedAt = DateTime.UtcNow
        });
    }
}

Subscribing to Events

public class OrderCreatedEventHandler : IEventSubscriber<OrderCreatedEvent>
{
    private readonly IInventoryService _inventoryService;
    private readonly INotificationService _notificationService;
    
    public async Task HandleAsync(OrderCreatedEvent @event)
    {
        // Update inventory
        await _inventoryService.ReserveItemsAsync(@event.OrderId);
        
        // Send notification to customer
        await _notificationService.SendOrderConfirmationAsync(@event.CustomerId, @event.OrderId);
        
        // Additional processing...
    }
}

public class OrderConfirmedEventHandler : IEventSubscriber<OrderConfirmedEvent>
{
    private readonly IPaymentService _paymentService;
    
    public async Task HandleAsync(OrderConfirmedEvent @event)
    {
        // Process payment
        await _paymentService.ProcessPaymentAsync(@event.OrderId);
    }
}

Tenant-Aware Events

public class TenantSubscriptionExpiredEvent : IntegrationEvent
{
    public Guid TenantId { get; set; }
    public DateTime ExpiredAt { get; set; }
}

public class TenantSubscriptionExpiredHandler : IEventSubscriber<TenantSubscriptionExpiredEvent>
{
    private readonly ITenantService _tenantService;
    
    public async Task HandleAsync(TenantSubscriptionExpiredEvent @event)
    {
        // Disable tenant access
        await _tenantService.DisableTenantAsync(@event.TenantId);
        
        // Send notification to tenant admin
        await _notificationService.SendSubscriptionExpiredNotificationAsync(@event.TenantId);
    }
}

Custom Event Contracts

public class UserProjectAssignedEvent : IntegrationEvent
{
    public Guid UserId { get; set; }
    public Guid ProjectId { get; set; }
    public string Role { get; set; }
    public DateTime AssignedAt { get; set; }
}

public class UserProjectAssignedHandler : IEventSubscriber<UserProjectAssignedEvent>
{
    private readonly IProjectService _projectService;
    private readonly INotificationService _notificationService;
    
    public async Task HandleAsync(UserProjectAssignedEvent @event)
    {
        // Add user to project
        await _projectService.AddUserToProjectAsync(@event.ProjectId, @event.UserId, @event.Role);
        
        // Send notification to user
        await _notificationService.SendProjectAssignmentNotificationAsync(@event.UserId, @event.ProjectId);
    }
}

Error Handling

public class ResilientEventHandler<T> : IEventSubscriber<T> where T : class
{
    private readonly IEventSubscriber<T> _innerHandler;
    private readonly ILogger<ResilientEventHandler<T>> _logger;
    
    public async Task HandleAsync(T message)
    {
        try
        {
            await _innerHandler.HandleAsync(message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error handling event {EventType}", typeof(T).Name);
            
            // Implement retry logic or dead letter queue
            throw;
        }
    }
}

Configuration

appsettings.json

{
  "EventBus": {
    "RabbitMQ": {
      "Host": "localhost",
      "Username": "guest",
      "Password": "guest",
      "VirtualHost": "/"
    },
    "RetryPolicy": {
      "MaxRetries": 3,
      "RetryInterval": "00:00:05"
    }
  }
}

Service Registration

public static class EventBusExtensions
{
    public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddMassTransit(x =>
        {
            // Register consumers
            x.AddConsumer<UserCreatedEventHandler>();
            x.AddConsumer<OrderCreatedEventHandler>();
            
            x.UsingRabbitMq((context, cfg) =>
            {
                var rabbitMqConfig = configuration.GetSection("EventBus:RabbitMQ").Get<RabbitMqConfig>();
                
                cfg.Host(rabbitMqConfig.Host, rabbitMqConfig.VirtualHost, h =>
                {
                    h.Username(rabbitMqConfig.Username);
                    h.Password(rabbitMqConfig.Password);
                });
                
                cfg.ConfigureEndpoints(context);
            });
        });
        
        services.AddScoped<IEventPublisher, EventPublisher>();
        
        return services;
    }
}

Dependencies

  • MassTransit - Message bus and routing
  • MassTransit.AspNetCore - ASP.NET Core integration
  • MassTransit.RabbitMQ - RabbitMQ transport
  • RabbitMQ.Client - RabbitMQ client library

Best Practices

Event Design

// ✅ Good - Use integration events for cross-service communication
public class UserCreatedEvent : IntegrationEvent
{
    public Guid UserId { get; set; }
    public string Username { get; set; }
    public DateTime CreatedAt { get; set; }
}

// ❌ Avoid - Don't include sensitive data in events
public class UserCreatedEvent : IntegrationEvent
{
    public string Password { get; set; } // Sensitive data
    public string SSN { get; set; } // Sensitive data
}

Event Handling

// ✅ Good - Keep handlers focused and idempotent
public class OrderCreatedHandler : IEventSubscriber<OrderCreatedEvent>
{
    public async Task HandleAsync(OrderCreatedEvent @event)
    {
        // Check if already processed
        if (await IsAlreadyProcessedAsync(@event.OrderId))
            return;
            
        // Process the event
        await ProcessOrderAsync(@event);
        
        // Mark as processed
        await MarkAsProcessedAsync(@event.OrderId);
    }
}

// ❌ Avoid - Don't make handlers dependent on order
public class OrderCreatedHandler : IEventSubscriber<OrderCreatedEvent>
{
    public async Task HandleAsync(OrderCreatedEvent @event)
    {
        // This depends on other events being processed first
        var user = await GetUserAsync(@event.UserId);
        // ...
    }
}

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

License

Copyright © Inam Ul Haq. All rights reserved.

Support

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on eBuildingBlocks.EventBus:

Package Downloads
eBuildingBlocks.Infrastructure

Reusable building block for the ecosystem. Implements core cross-cutting concerns, infrastructure, or domain utilities for .NET applications.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 282 8/5/2025
1.0.6 266 8/5/2025
1.0.5 279 7/20/2025
1.0.4 117 7/19/2025
1.0.1 111 7/19/2025