HerrGeneral.Core 0.1.8-rc

This is a prerelease version of HerrGeneral.Core.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package HerrGeneral.Core --version 0.1.8-rc
                    
NuGet\Install-Package HerrGeneral.Core -Version 0.1.8-rc
                    
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="HerrGeneral.Core" Version="0.1.8-rc" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="HerrGeneral.Core" Version="0.1.8-rc" />
                    
Directory.Packages.props
<PackageReference Include="HerrGeneral.Core" />
                    
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 HerrGeneral.Core --version 0.1.8-rc
                    
#r "nuget: HerrGeneral.Core, 0.1.8-rc"
                    
#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 HerrGeneral.Core@0.1.8-rc
                    
#: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=HerrGeneral.Core&version=0.1.8-rc&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=HerrGeneral.Core&version=0.1.8-rc&prerelease
                    
Install as a Cake Tool

Herr General

Herr General is a Cqrs implementation with built in debug log for simple modular monolith. (strongly inspired from MediatR)

Implementation choice

One storage for all pro : no eventual consistency cons : no eventual consistency ⇒ doesn't scale

One transaction by command.

ReadModel as singleton.

All ids are System.Guid.

Result pattern but CreationResult return the id of the created object.

Installing Herr General with NuGet

Write side HerrGeneral.WriteSide or HerrGeneral.WriteSide.DDD

Read side HerrGeneral.ReadSide

Application or infrastructure layer HerrGeneral.Core

Registering with IServiceCollection

Herr General supports Microsoft.Extensions.DependencyInjection.Abstractions directly. To register write side commands and eventHandlers and read side eventHandlers:

services.UseHerrGeneral(scanner =>
        scanner
            .OnWriteSide(typeof(Person).Assembly, typeof(Person).Namespace!)
            .OnReadSide(typeof(PersonFriendRM).Assembly, typeof(PersonFriendRM).Namespace!));

Sample code

// Write Side
public record SetFriend : ChangeAggregate<Person>
{
    private readonly string _friend;

    public SetFriend(Guid aggregateId, string friend) : base(aggregateId) => _friend = friend;

    public class Handler : ChangeAggregateHandler<Person,SetFriend>
    {
        public Handler(CtorParams ctorParams) : base(ctorParams) { }

        protected override Person Handle(Person aggregate, SetFriend command) => 
            aggregate.SetFriend(command._friend, command.Id);
    }
}

// Read side
public record PersonFriendRM(Guid PersonId, string Person, string Friend)
{
    public class PersonFriendRMRepository : IEventHandler<FriendChanged>
    {
        private readonly Dictionary<Guid, PersonFriendRM> _personFriends = new();
        public Task Handle(FriendChanged notification, CancellationToken cancellationToken)
        {
            _personFriends[notification.AggregateId] = new PersonFriendRM(notification.AggregateId, notification.Person, notification.FriendName);
            return Task.CompletedTask;
        }

        public PersonFriendRM Get(Guid personId) => _personFriends[personId];
    }    
}

Debug logger output sample

←------------------ SetFriend <46a0deab-0485-403e-821a-834a96517a7c> thread<1> -------------------> || Publish Write Side on thread<1> HerrGeneral.SampleApplication.WriteSide.FriendChanged

|| Publish Read Side (1 event) on thread<1> HerrGeneral.SampleApplication.WriteSide.FriendChanged → Handle by HerrGeneral.SampleApplication.ReadSide.PersonFriendRM+PersonFriendRMRepository ←------------------ SetFriend Finished 00:00:00.0021475 -------------------/>

How it works

A user: Hey, I want to change my friend name. Application: Ok, give me the command and I will take care of the rest. I'll send you back a commandResult when I'm done.

In the application black box : Mediator: Anybody to handle this command ? CommandHandler: I"m here. CommandHandler: I'm done and I have some events to publish. WriteSideEventPublisher: That's my job. WriteSideEventPublisher: Anybody to handle this event on the write side ? (for each event). WriteSideEventHandler: Me (and I may have other events to publish). WriteSideEventPublisher: I'm done. CommandHandler: Thank you, now I can transmit all those events to the read side. ReadSideEventPublisher: Anybody to handle this event on the read side ? (for each event). ReadModel: Yes me. ReadSideEventPublisher: I'm done. CommandHandler: I'm done.

Application: Here is your command result.

HowItWorks.png

Result pattern

ChangeResult

Herr general return ChangeResult for ChangeCommand 3 states : Success, DomainError, PanicException

updateResult.Match(() =>
    {
        ...
    },
    error => ...,
    exception => ...);

CreationResult

Herr general return CreationResult for CreationCommand 3 states : Success<Guid>, DomainError, PanicException

creationResult.Match(id =>
    {
        ...
    },
    error => ...,
    exception => ...);
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on HerrGeneral.Core:

Package Downloads
HerrGeneral.Test.Extension

Helper methods for HerrGeneral testing

HerrGeneral.Core.DDD

Registration of dynamic handler for aggregate creation and update

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.17-rc 31 7/13/2025
0.1.16-rc 47 7/4/2025
0.1.15-rc 114 7/1/2025
0.1.14-rc 70 6/28/2025
0.1.13-rc 69 11/12/2024
0.1.9-rc 98 9/21/2023
0.1.8-rc 97 9/19/2023
0.1.7-rc 106 9/11/2023
0.1.6-rc 117 8/8/2023
0.1.5-rc 109 8/6/2023
0.1.4-rc 100 8/6/2023
0.1.3-rc 111 8/6/2023