Meadow.Framework.Infrastructure
2.0.0
dotnet add package Meadow.Framework.Infrastructure --version 2.0.0
NuGet\Install-Package Meadow.Framework.Infrastructure -Version 2.0.0
<PackageReference Include="Meadow.Framework.Infrastructure" Version="2.0.0" />
<PackageVersion Include="Meadow.Framework.Infrastructure" Version="2.0.0" />
<PackageReference Include="Meadow.Framework.Infrastructure" />
paket add Meadow.Framework.Infrastructure --version 2.0.0
#r "nuget: Meadow.Framework.Infrastructure, 2.0.0"
#:package Meadow.Framework.Infrastructure@2.0.0
#addin nuget:?package=Meadow.Framework.Infrastructure&version=2.0.0
#tool nuget:?package=Meadow.Framework.Infrastructure&version=2.0.0
Meadow Framework
A small, opinionated .NET library that wires MediatR-style dispatching, MassTransit (RabbitMQ) integration and a set of DDD primitives (AggregateRoot, Repository, UnitOfWork, ValueObject) to accelerate building maintainable, distributed applications.
Lightweight building blocks for domain-driven applications, messaging and application-level dispatching.
Table of Contents
- Overview
- Key features
- Prerequisites
- Quick start
- Configuration
- Usage examples
- Command + Handler
- Publishing integration events
- Repository + Unit of Work
- Registered services
- Architecture (sequence)
- Contributing
- Development
- License
Overview
This repository provides a reusable set of abstractions, DI wiring and integrations commonly used in microservice-style .NET projects:
- Application-level dispatchers and handler discovery (command / query / event handlers)
- MassTransit integration with RabbitMQ for integration events
- DDD primitives (AggregateRoot, EntityBase, ValueObject, Repository, UnitOfWork)
- Outbox support and basic exception / API problem handling middleware
The goal is to reduce boilerplate and let teams focus on domain logic and message flows.
Key features
- Automatic DI registration (scan assembly and register command/query/event handlers)
- MediatR-style dispatching via
IDispatcher/IQueryDispatcher/ICommandDispatcher - Integration events publishing with MassTransit (RabbitMQ)
- DDD primitives and repository/unit-of-work abstractions
- Exception middleware and API problem details helpers
Prerequisites
- .NET 6+ SDK (examples use the minimal host style)
- (Optional) RabbitMQ instance for MassTransit
Quick start
Register the framework when building your host (example for .NET 6+ minimal hosting):
using Framework.Infrastructure; // adjust namespace if different
var builder = WebApplication.CreateBuilder(args);
// register the framework and scan the current assembly (or pass any assembly that contains handlers)
builder.Services.AddFramework(builder.Configuration, typeof(Program).Assembly);
var app = builder.Build();
app.UseMiddleware<Framework.Infrastructure.ErrorHandlerMiddleware>(); // optional, if present
app.MapControllers();
app.Run();
Notes:
- The example assumes an extension method
AddFramework(IConfiguration, Assembly)is exposed by the library. If your project uses a different type or assembly for discovery, pass that assembly instead.
Configuration
A minimal appsettings.json example with RabbitMQ settings consumed by MassTransit integration:
{
"MassTransit": {
"Host": "rabbitmq://localhost",
"Username": "guest",
"Password": "guest",
"VirtualHost": "/"
},
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=MyDb;Trusted_Connection=True;"
}
}
Usage examples
Command + handler (example)
// command (record or class)
public record CreateOrderCommand(Guid OrderId, decimal Total);
// handler (implements the framework's abstraction)
public class CreateOrderHandler : ICommandHandler<CreateOrderCommand, Result>
{
private readonly IRepository<Order> _orders;
public CreateOrderHandler(IRepository<Order> orders) => _orders = orders;
public async Task<Result> Handle(CreateOrderCommand request, CancellationToken ct)
{
var order = Order.Create(request.OrderId, request.Total);
await _orders.AddAsync(order, ct);
await _orders.UnitOfWork.SaveChangesAsync(ct);
return Result.Success();
}
}
Publishing integration events (MassTransit)
public class OrderCreatedEvent
{
public Guid OrderId { get; init; }
public decimal Total { get; init; }
}
public class SomeService
{
private readonly IPublishEndpoint _publisher;
public SomeService(IPublishEndpoint publisher) => _publisher = publisher;
public Task PublishOrderCreated(Guid orderId, decimal total) =>
_publisher.Publish(new OrderCreatedEvent { OrderId = orderId, Total = total });
}
Repository + Unit of Work (conceptual)
// obtain via DI
IRepository<Order> orders = ...;
var order = await orders.GetAsync(orderId);
order.ApplyDomainEvent(new SomethingHappened(...));
await orders.UnitOfWork.SaveChangesAsync();
Registered services
When you call AddFramework(...), the library will register (examples — adjust to actual project API):
- Dispatchers / helpers
- IDispatcher
- ICommandDispatcher
- IQueryDispatcher
- IEventDispatcher
- Handler registrations (open or concrete)
- ICommandHandler<TCommand, TResult>
- IQueryHandler<TQuery, TResult>
- IEventHandler<TEvent>
- INotificationHandler<TNotification> (if MediatR is used)
- Repository / Persistence abstractions
- IRepository<T>
- IUnitOfWork
- IOutboxRepository (if outbox is implemented)
- Middleware
- ErrorHandlerMiddleware / ExceptionMiddleware (API problem mapping)
Core components
- EntityBase, AggregateRoot, ValueObject
- Specification and SpecificationEvaluator
- OutboxMessage and Outbox message state
- Mapping abstractions and common DTO helpers
Architecture (sequence)
sequenceDiagram
participant Client
participant API
participant Dispatcher
participant Handler
participant Repository
participant Bus
Client->>API: HTTP Request / Command
API->>Dispatcher: Send command
Dispatcher->>Handler: Invoke handler
Handler->>Repository: Persist changes
Handler->>Bus: Publish integration event
Bus->>OtherService: Deliver event
Contributing
- Open issues or PRs with a clear description and small, focused changes.
- Add unit tests for new behavior where applicable.
- Follow existing code style and run local builds before submitting.
Development
- Build:
dotnet build - Run tests (if present):
dotnet test - Linting / static analysis: follow repository CI configuration (if any)
If you add new handlers or domain types, ensure the assembly that contains them is included when calling AddFramework(...) so the DI scanner can discover and register handlers.
Publishing packages
This repository is configured to produce NuGet packages for the library projects (for example Framework.Abstractions and Framework.Infrastructure).
CI publishing
- Pushing a Git tag of the form
vX.Y.Z(for examplev1.2.3) to the repository triggers the GitHub Actions workflow.github/workflows/nuget-publish.yml, which will build, pack and push packages to nuget.org. - The workflow expects a repository secret named
NUGET_API_KEYcontaining a NuGet.org API key with permissions to push packages.
Local packing and push
A helper script scripts/pack-and-push.sh is provided. Examples:
- Dry-run pack (no push):
./scripts/pack-and-push.sh --version 1.2.3 --dry-run
- Pack and push to nuget.org (requires
NUGET_API_KEYenv var):
export NUGET_API_KEY="<your-nuget-api-key>"
./scripts/pack-and-push.sh --version 1.2.3
Inspecting generated packages
After packing, the .nupkgs/ directory will contain the generated nupkg files. You can view the embedded .nuspec with:
unzip -p .nupkgs/<PackageId>.<version>.nupkg *.nuspec
License
Specify a license for the repository (e.g., MIT). Add a LICENSE file at the repository root and update this section accordingly.
Contact For questions or contributions, open an issue in this repository or contact the maintainers listed in the project metadata.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net9.0
- Humanizer.Core (>= 2.14.1)
- Meadow.Framework.Abstractions (>= 2.0.0)
- Microsoft.EntityFrameworkCore (>= 9.0.1)
- Microsoft.EntityFrameworkCore.InMemory (>= 9.0.0)
- Microsoft.Extensions.Caching.Memory (>= 9.0.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.1)
- Microsoft.Extensions.DependencyInjection (>= 9.0.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.2)
- Microsoft.Extensions.Hosting (>= 9.0.1)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 9.0.3)
- Quartz.Extensions.Hosting (>= 3.13.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|