An open API service indexing awesome lists of open source software.

https://github.com/monbsoft/brilliantmediator

RadiantMediator is a high-performance implementation of the Mediator pattern that focuses on simplicity and speed.
https://github.com/monbsoft/brilliantmediator

Last synced: 4 months ago
JSON representation

RadiantMediator is a high-performance implementation of the Mediator pattern that focuses on simplicity and speed.

Awesome Lists containing this project

README

          

# BrilliantMediator

![License](https://img.shields.io/badge/license-MIT-blue.svg)
![.NET](https://img.shields.io/badge/.NET-9%2B-blue)
![NuGet](https://img.shields.io/badge/NuGet-BrilliantMediator-blue)

**Ultra-lightweight, zero-reflection mediator for .NET with blazing performance.**

BrilliantMediator is a high-performance implementation of the Mediator pattern that focuses on simplicity and speed.

## ✨ Key Features

- ⚡ **Zero Reflection** - Uses compiled generics for maximum performance
- 🚀 **Blazing Fast** - Overhead approaching direct method calls (~50ns per operation)
- 🎯 **Type-Safe** - Full compile-time checking
- 📦 **Tiny** - ~100 lines of core code
- 🔧 **Simple** - Easy to understand and maintain
- 🌐 **Framework Agnostic** - Works with any .NET application
- 📋 **CQRS Ready** - Commands and Queries out of the box

## Installation

```bash
dotnet add package BrilliantMediator
```

Or from NuGet:
```
Install-Package BrilliantMediator
```

## Quick Start

### 1. Define a Command

```csharp
using BrilliantMediator.Abstractions.Commands;

public class CreateUserCommand : ICommand
{
public string Name { get; set; }
public string Email { get; set; }
}

public class CreateUserResult
{
public Guid UserId { get; set; }
public bool Success { get; set; }
}
```

### 2. Create a Handler

```csharp
using BrilliantMediator.Abstractions.Handlers;

public class CreateUserCommandHandler : ICommandHandler
{
private readonly IUserRepository _repository;

public CreateUserCommandHandler(IUserRepository repository)
{
_repository = repository;
}

public async Task Handle(CreateUserCommand command)
{
var user = new User { Id = Guid.NewGuid(), Name = command.Name, Email = command.Email };
await _repository.AddAsync(user);

return new CreateUserResult { UserId = user.Id, Success = true };
}
}
```

### 3. Register and Use

```csharp
using BrilliantMediator.Core;

// Create mediator
var mediator = new Mediator();

// Register handler
var handler = new CreateUserCommandHandler(userRepository);
mediator.RegisterCommandHandler(handler);

// Use it
var result = await mediator.Send(
new CreateUserCommand { Name = "John", Email = "john@example.com" }
);
```

## Concepts

### Commands

Commands represent actions that modify state.

#### Command without Response

```csharp
public class SendEmailCommand : ICommand
{
public string To { get; set; }
public string Subject { get; set; }
}

public class SendEmailCommandHandler : ICommandHandler
{
public async Task Handle(SendEmailCommand command)
{
// Send email
}
}

// Usage
await mediator.Send(new SendEmailCommand { To = "user@example.com", Subject = "Hello" });
```

#### Command with Response

```csharp
public class CalculateCommand : ICommand
{
public int A { get; set; }
public int B { get; set; }
}

public class CalculateCommandHandler : ICommandHandler
{
public async Task Handle(CalculateCommand command)
{
return command.A + command.B;
}
}

// Usage
var result = await mediator.Send(
new CalculateCommand { A = 5, B = 3 }
);
Console.WriteLine(result); // 8
```

### Queries

Queries represent read operations that don't modify state.

```csharp
public class GetUserQuery : IQuery
{
public Guid UserId { get; set; }
}

public class GetUserQueryHandler : IQueryHandler
{
private readonly IUserRepository _repository;

public GetUserQueryHandler(IUserRepository repository)
{
_repository = repository;
}

public async Task Handle(GetUserQuery query)
{
var user = await _repository.GetByIdAsync(query.UserId);
return new UserDto { Id = user.Id, Name = user.Name, Email = user.Email };
}
}

// Usage
var userDto = await mediator.Send(
new GetUserQuery { UserId = userId }
);
```

## Dependency Injection

### With Microsoft.Extensions.DependencyInjection

```csharp
using Microsoft.Extensions.DependencyInjection;
using BrilliantMediator.DependencyInjection;

var services = new ServiceCollection();

// Add BrilliantMediator and auto-discover handlers
services.AddBrilliantMediator(typeof(Program).Assembly);

// Or specify multiple assemblies
services.AddBrilliantMediator(
typeof(Program).Assembly,
typeof(SomeOtherClass).Assembly
);

var provider = services.BuildServiceProvider();
var mediator = provider.GetRequiredService();
```

### Why so fast?

1. **No Reflection** - Uses static generic registries
2. **Zero Allocations** - No intermediate objects created
3. **Compile-time Verification** - All dispatch decisions made at compile time
4. **JIT Inlining** - Methods small enough to inline

## Architecture

BrilliantMediator uses a unique approach based on static generic registries:

```csharp
// Internally:
private sealed class CommandHandlerRegistry where TCommand : ICommand
{
public static ICommandHandler Instance { get; set; }
}

// When you call Send(), the JIT directly accesses this static field
// No dictionaries, no Type lookups, no reflection
```

This ensures:
- **O(1)** lookup time for any command/query
- **Zero runtime overhead** compared to direct method calls
- **Full type safety** at compile time

## When to Use BrilliantMediator

✅ **Use BrilliantMediator if:**
- Performance is critical
- You want a simple, minimal implementation
- You're building an MVP
- You want to avoid external dependencies
- You need CQRS pattern

## Examples

### Example: E-Commerce Order Processing

```csharp
// Command
public class PlaceOrderCommand : ICommand
{
public Guid UserId { get; set; }
public List Items { get; set; }
}

public class PlaceOrderResult
{
public Guid OrderId { get; set; }
public decimal TotalAmount { get; set; }
}

// Handler
public class PlaceOrderCommandHandler : ICommandHandler
{
private readonly IOrderRepository _orderRepo;
private readonly IPaymentService _paymentService;

public PlaceOrderCommandHandler(IOrderRepository orderRepo, IPaymentService paymentService)
{
_orderRepo = orderRepo;
_paymentService = paymentService;
}

public async Task Handle(PlaceOrderCommand command)
{
var order = new Order
{
Id = Guid.NewGuid(),
UserId = command.UserId,
Items = command.Items,
CreatedAt = DateTime.UtcNow
};

var totalAmount = order.Items.Sum(i => i.Price * i.Quantity);
order.TotalAmount = totalAmount;

await _paymentService.ProcessPayment(command.UserId, totalAmount);
await _orderRepo.AddAsync(order);

return new PlaceOrderResult
{
OrderId = order.Id,
TotalAmount = totalAmount
};
}
}
```

## API Reference

### Mediator Methods

```csharp
// Send command without response
public async Task Send(TCommand command) where TCommand : ICommand

// Send command with response
public async Task Send(TCommand command)
where TCommand : ICommand

// Send query
public async Task Send(TQuery query)
where TQuery : IQuery

// Register command handler without response
public void RegisterCommandHandler(ICommandHandler handler)
where TCommand : ICommand

// Register command handler with response
public void RegisterCommandHandler(ICommandHandler handler)
where TCommand : ICommand

// Register query handler
public void RegisterQueryHandler(IQueryHandler handler)
where TQuery : IQuery
```

## Exception Handling

BrilliantMediator throws `HandlerNotRegisteredException` when a handler is not registered:

```csharp
try
{
await mediator.Send(new SomeCommand());
}
catch (HandlerNotRegisteredException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Author

Created with ❤️ for developers who care about performance.

## Support

- 📖 [Documentation](docs/)
- 🐛 [Issue Tracker](https://github.com/Monbsoft/BrilliantMediator/issues)
- 💬 [Discussions](https://github.com/Monbsoft/BrilliantMediator/discussions)