Brighter
A framework for building messaging apps with .NET and C#.
Install / Use
/learn @BrighterCommand/BrighterREADME
Brighter

Brighter is a Command Dispatcher and Command Processor framework for .NET. It enables you to build loosely coupled, maintainable applications using the Command pattern and supports both in-process and out-of-process messaging for microservices architectures. Its companion project, Darker, provides the query side for CQRS architectures.
Why Brighter?
- Command Dispatcher & Processor: Implements the Command pattern with a powerful middleware pipeline
- Clean Architecture Support: Perfect for implementing ports & adapters (hexagonal architecture)
- Messaging Made Simple: Abstract away messaging complexity - just write handlers
- Middleware Pipeline: Add cross-cutting concerns like logging, retry, and circuit breakers via attributes
- Multiple Transports: Support for RabbitMQ, AWS SNS+SQS, Kafka, Redis, and more
- Service Activator: Built-in message consumer for processing messages from queues
- Observability: Built-in support for distributed tracing and monitoring
Prerequisites
- .NET 8.0 or later - Brighter targets .NET 8, 9, and 10
- IDE - Visual Studio 2022+, VS Code, or JetBrains Rider
- Docker (optional) - For running message brokers and databases locally during development
Quick Start
Installation
dotnet add package Paramore.Brighter.Extensions.DependencyInjection
dotnet add package Microsoft.Extensions.Hosting
Basic Usage - Command Dispatcher
1. Define a Command
public class GreetingCommand(string name) : Command(Id.Random())
{
public string Name { get; } = name;
}
2. Create a Handler
public class GreetingCommandHandler : RequestHandler<GreetingCommand>
{
public override GreetingCommand Handle(GreetingCommand command)
{
Console.WriteLine($"Hello {command.Name}");
return base.Handle(command);
}
}
3. Configure and Send
// Setup
var builder = Host.CreateApplicationBuilder();
builder.Services.AddBrighter().AutoFromAssemblies();
var host = builder.Build();
var commandProcessor = host.Services.GetRequiredService<IAmACommandProcessor>();
// Send command (in-process)
commandProcessor.Send(new GreetingCommand("World"));
Note: For async operations, use
RequestHandlerAsync<T>and overrideHandleAsync()instead, then callSendAsync().
Out-of-Process Messaging
For microservices communication, Brighter can send and receive events via external message brokers. This typically involves two separate applications: a sender that posts events and a consumer that processes them.
First, install a transport package (pick one for your broker):
dotnet add package Paramore.Brighter.MessagingGateway.RMQ.Async # RabbitMQ
dotnet add package Paramore.Brighter.MessagingGateway.AWSSQS.V4 # AWS SQS (uses AWS SDK v4; use AWSSQS for v3)
dotnet add package Paramore.Brighter.MessagingGateway.Kafka # Kafka
For the consumer application, also install:
dotnet add package Paramore.Brighter.ServiceActivator.Extensions.DependencyInjection
dotnet add package Paramore.Brighter.ServiceActivator.Extensions.Hosting
1. Define an Event
public class GreetingEvent(string name) : Event(Id.Random())
{
public string Name { get; } = name;
}
2. Configure Producers and Post (Sender App)
var builder = Host.CreateApplicationBuilder();
var rmqConnection = new RmqMessagingGatewayConnection
{
AmpqUri = new AmqpUriSpecification(new Uri("amqp://guest:guest@localhost:5672")),
Exchange = new Exchange("paramore.brighter.exchange"),
};
var producerRegistry = new RmqProducerRegistryFactory(
rmqConnection,
[
new() { Topic = new RoutingKey("greeting.event"), RequestType = typeof(GreetingEvent) }
]).Create();
builder.Services.AddBrighter()
.AutoFromAssemblies()
.AddProducers(configure =>
{
configure.ProducerRegistry = producerRegistry;
});
var host = builder.Build();
var commandProcessor = host.Services.GetRequiredService<IAmACommandProcessor>();
// Post to external message broker
commandProcessor.Post(new GreetingEvent("World"));
3. Create an Event Handler (Consumer App)
public class GreetingEventHandler : RequestHandler<GreetingEvent>
{
public override GreetingEvent Handle(GreetingEvent @event)
{
Console.WriteLine($"Received greeting for {@event.Name}");
return base.Handle(@event);
}
}
4. Configure Consumer Subscriptions (Consumer App)
var builder = Host.CreateApplicationBuilder();
var rmqConnection = new RmqMessagingGatewayConnection
{
AmpqUri = new AmqpUriSpecification(new Uri("amqp://guest:guest@localhost:5672")),
Exchange = new Exchange("paramore.brighter.exchange"),
};
var rmqMessageConsumerFactory = new RmqMessageConsumerFactory(rmqConnection);
builder.Services.AddConsumers(options =>
{
options.Subscriptions =
[
new RmqSubscription<GreetingEvent>(
new SubscriptionName("greeting-subscription"),
new ChannelName("greeting.event"),
new RoutingKey("greeting.event"),
messagePumpType: MessagePumpType.Reactor,
makeChannels: OnMissingChannel.Create)
];
options.DefaultChannelFactory = new ChannelFactory(rmqMessageConsumerFactory);
}).AutoFromAssemblies();
builder.Services.AddHostedService<ServiceActivatorHostedService>();
var host = builder.Build();
await host.RunAsync();
Key Features
Middleware Pipeline
Add cross-cutting concerns via attributes on your handlers:
public class GreetingCommandHandler : RequestHandler<GreetingCommand>
{
[RequestLogging(step: 1, timing: HandlerTiming.Before)]
[UseResiliencePipeline("MyRetryPolicy", step: 2)]
public override GreetingCommand Handle(GreetingCommand command)
{
Console.WriteLine($"Hello {command.Name}");
return base.Handle(command);
}
}
Register resilience pipelines using Polly's ResiliencePipelineRegistry and pass them to AddBrighter():
var resiliencePipelineRegistry = new ResiliencePipelineRegistry<string>();
// Add Brighter's required internal pipelines
resiliencePipelineRegistry.AddBrighterDefault();
// Add your own pipelines
resiliencePipelineRegistry.TryAddBuilder("MyRetryPolicy",
(builder, _) => builder.AddRetry(new RetryStrategyOptions
{
BackoffType = DelayBackoffType.Linear,
Delay = TimeSpan.FromSeconds(1),
MaxRetryAttempts = 3
}));
builder.Services.AddBrighter(options =>
{
options.ResiliencePipelineRegistry = resiliencePipelineRegistry;
}).AutoFromAssemblies();
Available Middleware:
- Logging:
[RequestLogging]/[RequestLoggingAsync]- Log commands/events automatically - Retry & Circuit Breaker:
[UseResiliencePipeline]/[UseResiliencePipelineAsync]- Integrates with Polly 8.x for resilience - Validation:
[Validation]- Validate requests before handling - Custom middleware: Create your own attributes
Outbox Pattern for Reliable Messaging
Brighter implements the Outbox pattern to guarantee message delivery in distributed systems. Instead of calling Post directly, use DepositPost to write messages to the Outbox within your database transaction, then ClearOutbox to dispatch them after the transaction commits. This ensures consistency between your database state and published messages.
Supported Outbox Stores: PostgreSQL, MySQL, MSSQL, SQLite, DynamoDB, MongoDB. See the full documentation for configuration details.
Multiple Messaging Patterns
- Send/SendAsync: Commands - one sender → one handler (in-process only)
- Publish/PublishAsync: Events - one publisher → multiple handlers (in-process only)
- Post/PostAsync: Send a command or event to an external message broker for out-of-process handling
- Request-Reply: Synchronous RPC-style calls over async messaging
Supported Transports
- RabbitMQ (AMQP)
- AWS SQS + SNS
- Azure Service Bus
- Apache Kafka
- Redis Streams
- PostgreSQL & MSSQL (as message transports)
- In-Memory (for testing)
Use Cases
Clean Architecture / Hexagonal Architecture
Use Brighter as your application's port layer. Commands and Events represent your use cases, and handlers implement the application logic.
Microservices Integration
Abstract away messaging infrastructure. Developers write domain code (commands/events and handlers) while Brighter handles message routing, serialization, and transport.
Task Queue / Job Processing
Use Brighter's Service Activator to consume messages from queues and process them with retry, circuit breaker, and monitoring built-in.
Learn More
📚 Full Documentation - Comprehensive guides, tutorials, and API reference
Topics covered in the documentation:
- Advanced middleware and pipelines
- Outbox and
Related Skills
node-connect
339.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.9kCommit, push, and open a PR
