Arbiter.CommandQuery
1.6.0
dotnet add package Arbiter.CommandQuery --version 1.6.0
NuGet\Install-Package Arbiter.CommandQuery -Version 1.6.0
<PackageReference Include="Arbiter.CommandQuery" Version="1.6.0" />
<PackageVersion Include="Arbiter.CommandQuery" Version="1.6.0" />
<PackageReference Include="Arbiter.CommandQuery" />
paket add Arbiter.CommandQuery --version 1.6.0
#r "nuget: Arbiter.CommandQuery, 1.6.0"
#:package Arbiter.CommandQuery@1.6.0
#addin nuget:?package=Arbiter.CommandQuery&version=1.6.0
#tool nuget:?package=Arbiter.CommandQuery&version=1.6.0
Arbiter
A powerful, lightweight, and extensible implementation of the Mediator pattern and Command Query Responsibility Segregation (CQRS) for .NET applications.
Arbiter is designed for building clean, modular architectures like Vertical Slice Architecture and CQRS. It provides a comprehensive suite of libraries that work together to simplify complex application patterns while maintaining high performance and flexibility.
Key Features
- Clean Architecture: Perfect for Vertical Slice Architecture and CQRS patterns
- High Performance: Minimal overhead with efficient mediator implementation
- Extensible: Pipeline behaviors, custom handlers, and extensive customization options
- Observable: Built-in OpenTelemetry support for tracing and metrics
- Database Agnostic: Support for Entity Framework Core, MongoDB, and more
- Web Ready: Minimal API endpoints and MVC controller support
- Communication: Integrated email and SMS messaging capabilities
Table of Contents
- Quick Start
- Packages
- Core Libraries
- Data Providers
- Web Integration
- Documentation
- Samples
- Contributing
- License
Quick Start
Get started with Arbiter in just a few steps:
1. Install the Core Package
dotnet add package Arbiter.Mediation
2. Define a Request and Handler
// Define your request
public class GetUserQuery : IRequest<User>
{
public int UserId { get; set; }
}
// Implement the handler
public class GetUserHandler : IRequestHandler<GetUserQuery, User>
{
public async ValueTask<User> Handle(GetUserQuery request, CancellationToken cancellationToken)
{
// Your business logic here
return await GetUserFromDatabase(request.UserId);
}
}
3. Register Services
services.AddMediator();
services.AddTransient<IRequestHandler<GetUserQuery, User>, GetUserHandler>();
4. Use the Mediator
public class UserController : ControllerBase
{
private readonly IMediator _mediator;
public UserController(IMediator mediator) => _mediator = mediator;
[HttpGet("{id}")]
public async Task<User> GetUser(int id)
{
return await _mediator.Send(new GetUserQuery { UserId = id });
}
}
Packages
Core Libraries Packages
Library | Package | Description |
---|---|---|
Arbiter.Mediation | Lightweight and extensible implementation of the Mediator pattern | |
Arbiter.CommandQuery | Base package for Commands, Queries and Behaviors | |
Arbiter.Communication | Message template communication for email and SMS services |
Data Providers Packages
Library | Package | Description |
---|---|---|
Arbiter.CommandQuery.EntityFramework | Entity Framework Core handlers for the base Commands and Queries | |
Arbiter.CommandQuery.MongoDB | MongoDB handlers for the base Commands and Queries |
Web Integration Packages
Library | Package | Description |
---|---|---|
Arbiter.CommandQuery.Endpoints | Minimal API endpoints for base Commands and Queries | |
Arbiter.CommandQuery.Mvc | MVC Controllers for base Commands and Queries |
Observability Packages
Library | Package | Description |
---|---|---|
Arbiter.Mediation.OpenTelemetry | OpenTelemetry support for Arbiter.Mediation library |
Communication Providers Packages
Library | Package | Description |
---|---|---|
Arbiter.Communication.Azure | Communication implementation for Azure Communication Services | |
Arbiter.Communication.Twilio | Communication implementation for SendGrid and Twilio |
Core Libraries
Arbiter.Mediation
A lightweight and extensible implementation of the Mediator pattern for .NET applications, designed for clean, modular architectures like Vertical Slice Architecture and CQRS.
Mediation Features
- Request/Response Pattern: Handle requests with typed responses using
IRequest<TResponse>
andIRequestHandler<TRequest, TResponse>
- Notifications/Events: Publish events using
INotification
andINotificationHandler<TNotification>
- Pipeline Behaviors: Middleware-like cross-cutting concerns using
IPipelineBehavior<TRequest, TResponse>
- Dependency Injection: Seamless integration with .NET's DI container
- High Performance: Minimal allocations and efficient execution
- OpenTelemetry Ready: Built-in observability support
Installation
dotnet add package Arbiter.Mediation
Basic Usage
1. Define Request and Response
public class Ping : IRequest<Pong>
{
public string? Message { get; set; }
}
public class Pong
{
public string? Message { get; set; }
}
2. Implement Handler
public class PingHandler : IRequestHandler<Ping, Pong>
{
public async ValueTask<Pong> Handle(
Ping request,
CancellationToken cancellationToken = default)
{
// Simulate async work
await Task.Delay(100, cancellationToken);
return new Pong { Message = $"{request.Message} Pong" };
}
}
3. Define Pipeline Behavior (Optional)
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;
public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger)
{
_logger = logger;
}
public async ValueTask<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken = default)
{
_logger.LogInformation("Handling {RequestType}", typeof(TRequest).Name);
var response = await next(cancellationToken);
_logger.LogInformation("Handled {RequestType}", typeof(TRequest).Name);
return response;
}
}
4. Register Services
// Register Mediator services
services.AddMediator();
// Register handlers
services.AddTransient<IRequestHandler<Ping, Pong>, PingHandler>();
// Register pipeline behaviors (optional)
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
5. Use in Controllers
[ApiController]
[Route("api/[controller]")]
public class PingController : ControllerBase
{
private readonly IMediator _mediator;
public PingController(IMediator mediator) => _mediator = mediator;
[HttpGet]
public async Task<ActionResult<Pong>> Get(
[FromQuery] string? message = null,
CancellationToken cancellationToken = default)
{
var request = new Ping { Message = message ?? "Hello" };
var response = await _mediator.Send(request, cancellationToken);
return Ok(response);
}
}
Arbiter.Mediation.OpenTelemetry
Comprehensive observability support for Arbiter.Mediation with OpenTelemetry integration.
OpenTelemetry Installation
dotnet add package Arbiter.Mediation.OpenTelemetry
OpenTelemetry Features
- Distributed Tracing: Automatic tracing of all mediator operations
- Metrics: Built-in metrics for request duration, throughput, and errors
- Activity Enrichment: Rich contextual information in traces
- Zero Configuration: Works out of the box with minimal setup
Usage
// Register diagnostics
services.AddMediatorDiagnostics();
// Configure OpenTelemetry
services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddMediatorInstrumentation()
.AddConsoleExporter()
)
.WithMetrics(metrics => metrics
.AddMediatorInstrumentation()
.AddConsoleExporter()
);
Arbiter.CommandQuery
A comprehensive Command Query Responsibility Segregation (CQRS) framework built on top of the mediator pattern.
CommandQuery Features
- CQRS Implementation: Clear separation between commands and queries
- Pre-built Operations: Common CRUD operations out of the box
- Generic Handlers: Reusable handlers for typical data operations
- Smart Behaviors: Caching, auditing, validation, and soft delete support
- Auto Mapping: Built-in view model to data model mapping
- Advanced Querying: Filter, sort, and pagination support
- Multi-tenancy Ready: Built-in tenant isolation support
Package Installation
dotnet add package Arbiter.CommandQuery
Service Registration
services.AddCommandQuery();
Built-in Commands and Queries
The library provides several pre-built commands and queries for common operations:
Entity Queries:
EntityIdentifierQuery<TKey, TReadModel>
- Get entity by IDEntitySelectQuery<TReadModel>
- Query entities with filtering and sortingEntityPagedQuery<TReadModel>
- Paginated entity queries
Entity Commands:
EntityCreateCommand<TKey, TCreateModel, TReadModel>
- Create new entitiesEntityUpdateCommand<TKey, TUpdateModel, TReadModel>
- Update existing entitiesEntityUpsertCommand<TKey, TUpsertModel, TReadModel>
- Create or update entitiesEntityDeleteCommand<TKey, TReadModel>
- Delete entities
Example Usage
Query by ID:
var principal = new ClaimsPrincipal(new ClaimsIdentity(new[] {
new Claim(ClaimTypes.Name, "JohnDoe")
}));
var query = new EntityIdentifierQuery<int, ProductReadModel>(principal, 123);
var result = await mediator.Send(query);
Query with Filtering:
var filter = new EntityFilter { Name = "Status", Operator = "eq", Value = "Active" };
var sort = new EntitySort { Name = "Name", Direction = "asc" };
var query = new EntitySelectQuery<ProductReadModel>(principal, filter, sort);
var result = await mediator.Send(query);
Update Command:
var updateModel = new ProductUpdateModel
{
Name = "Updated Product",
Description = "Updated description",
Price = 29.99m
};
var command = new EntityUpdateCommand<int, ProductUpdateModel, ProductReadModel>(principal, 123, updateModel);
var result = await mediator.Send(command);
Data Providers
Arbiter.CommandQuery.EntityFramework
Entity Framework Core integration providing ready-to-use handlers for all base commands and queries.
CommandQuery EntityFramework Installation
dotnet add package Arbiter.CommandQuery.EntityFramework
CommandQuery EntityFramework Features
- Complete CRUD Operations: Pre-built handlers for all entity operations
- Change Tracking: Automatic audit fields and soft delete support
- Optimized Queries: Efficient EF Core query patterns
- Transaction Support: Proper transaction management
- Bulk Operations: Support for bulk insert/update operations
Setup
// Add Entity Framework Core services
services.AddDbContext<TrackerContext>(options =>
options.UseSqlServer(connectionString)
);
// Register Command Query services
services.AddCommandQuery();
// Register mappers and validators
services.AddSingleton<IMapper, MyMapper>();
services.AddSingleton<IValidator, MyValidator>();
// Register Entity Framework handlers for each entity
services.AddEntityQueries<TrackerContext, Product, int, ProductReadModel>();
services.AddEntityCommands<TrackerContext, Product, int, ProductReadModel, ProductCreateModel, ProductUpdateModel>();
Arbiter.CommandQuery.MongoDB
MongoDB integration providing handlers for all base commands and queries with document database optimizations.
dotnet add package Arbiter.CommandQuery.MongoDB
MongoDB Setup
// Add MongoDB Repository services
services.AddMongoRepository("Tracker");
services.AddCommandQuery();
// Register mappers and validators
services.AddSingleton<IMapper, MyMapper>();
services.AddSingleton<IValidator, MyValidator>();
// Register MongoDB handlers for each entity
services.AddEntityQueries<IMongoEntityRepository<Product>, Product, string, ProductReadModel>();
services.AddEntityCommands<IMongoEntityRepository<Product>, Product, string, ProductReadModel, ProductCreateModel, ProductUpdateModel>();
Web Integration
Arbiter.CommandQuery.Endpoints
Minimal API endpoints that automatically expose your commands and queries as REST APIs.
dotnet add package Arbiter.CommandQuery.Endpoints
Endpoints Setup
var builder = WebApplication.CreateBuilder(args);
// Add endpoint services
builder.Services.AddEndpointRoutes();
var app = builder.Build();
// Map endpoint routes
app.MapEndpointRoutes();
app.Run();
Custom Endpoint:
public class ProductEndpoint : EntityCommandEndpointBase<int, ProductReadModel, ProductReadModel, ProductCreateModel, ProductUpdateModel>
{
public ProductEndpoint(ILoggerFactory loggerFactory)
: base(loggerFactory, "Product")
{
}
}
// Register the endpoint
builder.Services.AddSingleton<IEndpointRoute, ProductEndpoint>();
Arbiter.CommandQuery.Mvc
MVC Controllers for base Commands and Queries with full ASP.NET Core integration.
dotnet add package Arbiter.CommandQuery.Mvc
Communication
Arbiter.Communication
A flexible message templating system for email and SMS communications with support for multiple providers.
dotnet add package Arbiter.Communication
Communication Providers
Azure Communication Services:
dotnet add package Arbiter.Communication.Azure
SendGrid and Twilio:
dotnet add package Arbiter.Communication.Twilio
Documentation
- Complete Documentation - Comprehensive guides and API reference
- Quick Start Guide - Get up and running quickly
- Architecture Patterns - Best practices and patterns
Samples
Explore practical examples in the samples directory:
- Entity Framework Sample - Complete CRUD operations with EF Core
- MongoDB Sample - Document database implementation
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (git checkout -b feature/amazing-feature)
- Commit your changes (git commit -m 'Add amazing feature')
- Push to the branch (git push origin feature/amazing-feature)
- Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
If you find this project useful, please consider:
- Starring the repository
- Reporting issues
- Contributing improvements
- Spreading the word
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. 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. |
-
net8.0
- Arbiter.Mediation (>= 1.6.0)
- Microsoft.Bcl.Memory (>= 9.0.8)
- Microsoft.Extensions.Caching.Abstractions (>= 9.0.8)
- Microsoft.Extensions.Http (>= 9.0.8)
- System.Linq.Dynamic.Core (>= 1.6.7)
- System.Text.Json (>= 9.0.8)
- SystemTextJsonPatch (>= 4.2.0)
-
net9.0
- Arbiter.Mediation (>= 1.6.0)
- Microsoft.Extensions.Caching.Abstractions (>= 9.0.8)
- Microsoft.Extensions.Http (>= 9.0.8)
- System.Linq.Dynamic.Core (>= 1.6.7)
- System.Text.Json (>= 9.0.8)
- SystemTextJsonPatch (>= 4.2.0)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Arbiter.CommandQuery:
Package | Downloads |
---|---|
Arbiter.CommandQuery.Endpoints
Command Query Responsibility Segregation (CQRS) framework based on mediator pattern using Minimal API endpoints |
|
Arbiter.CommandQuery.EntityFramework
Command Query Responsibility Segregation (CQRS) framework based on mediator pattern using Entity Framework as the data store handler |
|
Arbiter.CommandQuery.MongoDB
Command Query Responsibility Segregation (CQRS) framework based on mediator pattern using Mongo DB as the data store handler |
|
Arbiter.CommandQuery.Mvc
Command Query Responsibility Segregation (CQRS) framework based on mediator pattern using ASP.NET MVC Controllers |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.6.0 | 0 | 9/3/2025 |
1.5.0 | 113 | 8/30/2025 |
1.4.4 | 170 | 8/19/2025 |
1.4.3 | 163 | 8/11/2025 |
1.4.2 | 120 | 7/31/2025 |
1.4.1 | 184 | 7/26/2025 |
1.4.0 | 496 | 7/22/2025 |
1.3.1 | 444 | 7/21/2025 |
1.3.0 | 166 | 7/13/2025 |
1.2.7 | 229 | 6/16/2025 |
1.2.6 | 128 | 6/6/2025 |
1.2.5 | 173 | 6/5/2025 |
1.2.4 | 169 | 6/4/2025 |
1.2.3 | 171 | 6/4/2025 |
1.2.2 | 179 | 6/3/2025 |
1.2.1 | 172 | 6/1/2025 |
1.2.0 | 169 | 6/1/2025 |
1.1.2 | 169 | 5/28/2025 |
1.1.0 | 180 | 5/20/2025 |
1.0.0 | 182 | 5/6/2025 |
1.0.0-beta.7 | 127 | 5/1/2025 |
1.0.0-beta.6 | 132 | 4/29/2025 |
1.0.0-beta.5 | 137 | 4/29/2025 |
1.0.0-beta.4 | 137 | 4/29/2025 |
1.0.0-beta.3 | 134 | 4/23/2025 |