Loading repository data…
Loading repository data…
BrighterCommand / repository
A framework for building messaging apps with .NET and C#.

📖 New to Brighter? Check out the full documentation for guides, tutorials, and API reference.
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.
dotnet add package Paramore.Brighter.Extensions.DependencyInjection
dotnet add package Microsoft.Extensions.Hosting
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().
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
public class GreetingEvent(string name) : Event(Id.Random())
{
public string Name { get; } = name;
}
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"));
public class GreetingEventHandler : RequestHandler<GreetingEvent>
{
public override GreetingEvent Handle(GreetingEvent @event)
{
Console.WriteLine($"Received greeting for {@event.Name}");
return base.Handle(@event);
}
}
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();
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:
[RequestLogging] / [RequestLoggingAsync] - Log commands/events automatically[UseResiliencePipeline] / [UseResiliencePipelineAsync] - Integrates with Polly 8.x for resilience[Validation] - Validate requests before handlingBrighter 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.
Use Brighter as your application's port layer. Commands and Events represent your use cases, and handlers implement the application logic.
Abstract away messaging infrastructure. Developers write domain code (commands/events and handlers) while Brighter handles message routing, serialization, and transport.
Use Brighter's Service Activator to consume messages from queues and process them with retry, circuit breaker, and monitoring built-in.
📚 Full Documentation - Comprehensive guides, tutorials, and API reference
Topics covered in the documentation:
brighterLatest stable releases are available on NuGet.
Core Packages:
Paramore.Brighter - Core command processor and dispatcherParamore.Brighter.Extensions.DependencyInjection - AddBrighter() for .NET dependency injectionParamore.Brighter.ServiceActivator - Message pump for consuming messagesParamore.Brighter.ServiceActivator.Extensions.DependencyInjection - AddConsumers() for .NET dependency injectionParamore.Brighter.ServiceActivator.Extensions.Hosting - Run the message pump as a hosted serviceTransport Packages:
Paramore.Brighter.MessagingGateway.RMQ.Async - RabbitMQParamore.Brighter.MessagingGateway.AWSSQS.V4 - AWS SQS+SNS (AWS SDK v4; use AWSSQS for v3)Paramore.Brighter.MessagingGateway.Kafka - Apache Kafka