RootBlocks 0.9.0

dotnet add package RootBlocks --version 0.9.0
                    
NuGet\Install-Package RootBlocks -Version 0.9.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RootBlocks" Version="0.9.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RootBlocks" Version="0.9.0" />
                    
Directory.Packages.props
<PackageReference Include="RootBlocks" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RootBlocks --version 0.9.0
                    
#r "nuget: RootBlocks, 0.9.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RootBlocks@0.9.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RootBlocks&version=0.9.0
                    
Install as a Cake Addin
#tool nuget:?package=RootBlocks&version=0.9.0
                    
Install as a Cake Tool

RootBlocks

NuGet release License: MIT

RootBlocks is a set of .NET packages that provide the building blocks of Domain-Driven Design (DDD). It covers entities, aggregate roots, value objects, enumeration classes, domain events, a unit of work with a transactional outbox, and persistence helpers for Entity Framework Core and raw SQL. You write the business rules and RootBlocks handles the repetitive parts.

public class Post : Entity< PostId >, IAggregateRoot
{
    public string Title { get; private set; }
    public DateTime? PublishedOn { get; private set; }

    public Post( string title ) : base( PostId.New() ) => Title = title;

    public void Publish()
    {
        PublishedOn = DateTime.UtcNow;
        AddDomainEvent( new PostPublished( Id ) );
    }
}

// In a command handler
var post = await posts.GetByIdAsync( postId, cancellationToken );
post.Publish();
unitOfWork.RegisterDirty( post );
await unitOfWork.CommitAsync( cancellationToken ); // saves the post and PostPublished together, then publishes it

Features

  • Domain model: Entity<T> with domain events and audit dates, IAggregateRoot, ValueObject with structural equality, Enumeration classes, DomainEvent with causation and correlation IDs, and domain exceptions.
  • Unit of work for EF Core: commits aggregates, collects their domain events, and checks optimistic concurrency with a RowVersion.
  • Transactional outbox: events are saved in the same transaction as the change, published straight after, and retried with exponential backoff by a background dispatcher. One outbox per context, so each module of a modular monolith has its own. Plain SQL only: no Service Broker, so it runs on Azure SQL and in containers.
  • Soft delete, UTC dates and auditing handled by the base DbContext and entity configurations.
  • CQRS read side: an IConnectionFactory for Dapper or ADO.NET, with drivers for SQL Server, PostgreSQL, MySQL, Oracle and SQLite.
  • Integrations: MediatR for in-process events, Serilog for log context, and transformers for the built-in ASP.NET Core OpenAPI document.

Packages

Package Target What it gives you
RootBlocks netstandard2.1 Core DDD types (Entity<T>, IAggregateRoot, ValueObject, Enumeration, DomainEvent), repository and unit-of-work abstractions, pagination, exceptions and small helpers. Every other package depends on it.
RootBlocks.Persistence.EntityFramework net10.0 EF Core base DbContext, entity configurations, UnitOfWork, soft delete, optimistic concurrency and the transactional outbox.
RootBlocks.Persistence netstandard2.1 An IConnectionFactory for raw ADO.NET or Dapper queries (the read side of CQRS). Use it with one of the drivers below.
RootBlocks.Persistence.SqlClient netstandard2.1 SQL Server driver (Microsoft.Data.SqlClient).
RootBlocks.Persistence.Npgsql net10.0 PostgreSQL driver (Npgsql).
RootBlocks.Persistence.MySqlClient netstandard2.1 MySQL driver (MySql.Data).
RootBlocks.Persistence.Oracle netstandard2.1 Oracle driver (Oracle.ManagedDataAccess.Client, from CYQ.Data.Oracle).
RootBlocks.Persistence.SQLite netstandard2.1 SQLite driver (System.Data.SQLite).
RootBlocks.Messaging.MediatR net10.0 An IEventPublisher that dispatches domain events through MediatR.
RootBlocks.Serialization net10.0 A System.Text.Json converter that round-trips domain events, private setters included.
RootBlocks.Serialization.Newtonsoft.Json net10.0 The Newtonsoft JSON Patch input formatter for MVC apps. Minimal APIs do not need it.
RootBlocks.Logging.Serilog net10.0 A Serilog implementation of ILogContext, plus a preset logging setup for apps that have no appsettings.json.
RootBlocks.AspNetCore.OpenApi net10.0 Transformers for the built-in Microsoft.AspNetCore.OpenApi document, such as JSON Patch examples. Works with any UI.

See Target frameworks for what each target means for your project.

Installation

Install the packages you need from NuGet:

dotnet add package RootBlocks
dotnet add package RootBlocks.Persistence.EntityFramework
dotnet add package RootBlocks.Messaging.MediatR
dotnet add package RootBlocks.Persistence.SqlClient   # or .Npgsql, .MySqlClient, .Oracle, .SQLite

RootBlocks does not ship an identifier type. Entity<T> accepts any T : IEquatable<T>, such as Guid, int or string. For strongly-typed IDs like PostId, use the separate StronglyTypedIdentifier library, which also provides the EF Core and ASP.NET Core integration for those IDs. The examples in these docs use it.

Then wire it up in your composition root:

builder.Services
       .AddMediatR( cfg => cfg.RegisterServicesFromAssembly( typeof( PublishPostCommand ).Assembly ) )
       .AddMessaging()                                     // IEventPublisher through MediatR
       .AddSqlClientPersistence( connectionString )        // IConnectionFactory for queries
       .AddDbContext< Context >( o => o.UseSqlServer( connectionString ) )
       .AddOutbox< Context >( builder.Configuration )      // when the context calls modelBuilder.ApplyOutbox()
       .AddScoped< IUnitOfWork, UnitOfWork >()
       .AddScoped< IPostRepository, PostRepository >();

Getting started builds this up step by step.

Upgrading from 0.5

Version 0.6 rewrote the outbox: it is now per context, retried, and free of Service Broker. The old API still compiles with obsolete warnings. See Upgrading to 0.6 for the migration.

Documentation

Sample

samples/Blogs is a minimal API that uses every package together. It has three aggregates (Person, Blog, Post), MediatR commands, EF Core with the outbox for writes and Dapper for reads, and a Scalar UI over the OpenAPI document. See the sample guide.

dotnet run --project samples/Blogs/src/Blogs.Api/

Building from source

dotnet build RootBlocks.slnx
dotnet test     # the EF tests need Docker for SQL Server

The SDK is pinned in global.json. See Contributing for conventions, versioning and releases.

License

MIT © Sébastien de Salvador

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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 was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on RootBlocks:

Package Downloads
RootBlocks.AspNetCore.Swashbuckle

Provides Filters to render certain objects from the RootBlocks library correctly in Swagger.

RootBlocks.Serialization

Utilities and extensions for enhanced serialization in the RootBlocks library.

RootBlocks.Messaging.MediatR

Provides a MediatR implementation of the IEventPublisher from the RootBlocks library, mainly used to dispatch events internally.

RootBlocks.Logging.Serilog

Provides a Serilog implementation of the ILogContext from the RootBlocks library + a couple of easy to use Add methods to add easily add Serilog to projects without appsettings.json like Azure Functions.

RootBlocks.Serialization.Newtonsoft.Json

Helper to add support for JSON Patch requests which currently not supported by System.Text.Json.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.9.0 306 11/5/2026
0.8.0 188 11/3/2026
0.6.0 330 10/27/2026
0.5.0 155 10/24/2026
0.4.0 1,405 12/12/2024
0.3.1 546 11/3/2024
0.3.0 325 11/3/2024
0.2.0 383 6/2/2024
0.1.1 227 6/2/2024