ProDispatch is a lightweight, in-process dispatcher inspired by MediatR. It supports commands, queries, notifications, and pluggable pipeline behaviors without requiring a heavy dependency injection container.
- MediatR-Compatible API: Use
IRequest/IRequestHandlerfor seamless migration from MediatR - CQRS Support: Dedicated
ICommand/IQueryinterfaces with their respective handlers - Flexible Pipeline Behaviors: Scope behaviors to commands-only, queries-only, or all requests
- Notifications: Fan-out to multiple handlers with
INotification - No External Dependencies: Ships as a single library with no runtime dependencies
- Fully Tested: Comprehensive test coverage with samples, integration tests, and benchmarks
- Build the solution:
dotnet build ProDispatch.slnx
- Run the sample console app:
dotnet run --project samples/ProDispatch.Examples.Console/ProDispatch.Examples.Console.csproj
- Run tests:
dotnet test ProDispatch.slnx
- Run benchmarks:
dotnet run -c Release --project benchmarks/ProDispatch.Benchmarks/ProDispatch.Benchmarks.csproj
- Library: src/ProDispatch
- Sample: samples/ProDispatch.Examples.Console
- Tests: tests/ProDispatch.Tests and tests/ProDispatch.IntegrationTests
- Benchmarks: benchmarks/ProDispatch.Benchmarks
- Docs: docs (see getting-started, advanced-usage, performance, migration-from-mediatr)
// Define a request
public record GetUserQuery(Guid Id) : IRequest<User>;
// Define a handler
public class GetUserQueryHandler : IRequestHandler<GetUserQuery, User>
{
public Task<User> HandleAsync(GetUserQuery request, CancellationToken cancellationToken)
{
// ... fetch user
}
}
// Send the request
var user = await dispatcher.Send(new GetUserQuery(userId));// Commands
public record CreateUserCommand(string Name) : ICommand<Guid>;
public class CreateUserHandler : ICommandHandler<CreateUserCommand, Guid> { }
// Queries
public record GetUserByIdQuery(Guid Id) : IQuery<User>;
public class GetUserByIdHandler : IQueryHandler<GetUserByIdQuery, User> { }
// Usage
var userId = await dispatcher.SendAsync(new CreateUserCommand("Alice"));
var user = await dispatcher.SendAsync(new GetUserByIdQuery(userId));// Apply to all requests
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> { }
// Apply only to commands
public class TransactionBehavior<TRequest, TResponse> :
IPipelineBehavior<TRequest, TResponse>,
ICommandPipelineBehavior { }
// Apply only to queries
public class CachingBehavior<TRequest, TResponse> :
IPipelineBehavior<TRequest, TResponse>,
IQueryPipelineBehavior { }See docs/getting-started.md for a full walkthrough and docs/advanced-usage.md for customization tips.
- GitHub Actions build, test, and Sonar analysis via .github/workflows/ci.yml
- Security scanning via .github/workflows/codeql.yml
- NuGet packaging/release automation via .github/workflows/release.yml
Please read CONTRIBUTING.md and CODE_OF_CONDUCT.md before opening issues or pull requests. Suggestions and improvements are welcome.