PraetoR 1.0.1-alpha

This is a prerelease version of PraetoR.
dotnet add package PraetoR --version 1.0.1-alpha
                    
NuGet\Install-Package PraetoR -Version 1.0.1-alpha
                    
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="PraetoR" Version="1.0.1-alpha" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PraetoR" Version="1.0.1-alpha" />
                    
Directory.Packages.props
<PackageReference Include="PraetoR" />
                    
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 PraetoR --version 1.0.1-alpha
                    
#r "nuget: PraetoR, 1.0.1-alpha"
                    
#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 PraetoR@1.0.1-alpha
                    
#: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=PraetoR&version=1.0.1-alpha&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=PraetoR&version=1.0.1-alpha&prerelease
                    
Install as a Cake Tool

PraetoR 🏛️

License: MIT

PraetoR is a lightweight, in-process command and event dispatcher for .NET. It helps you decouple your application's components by enforcing a clean separation between issuing commands and handling business logic.

The name comes from the PraetoRs of ancient Rome, magistrates given the authority to lead armies and issue commands. This library acts as the central authority in your application, receiving commands and ensuring they are executed by the correct handler.

Core Concepts

  • IPraetoR: The central service you inject into your classes to send commands and publish dicta (events).
  • Command: A message that is sent to a single handler and represents an intention to change the system's state or retrieve data.
    • IOperation<TResult>: For commands that return a value (Queries or Commands).
    • IOperation: For commands that do not return a value.
  • Dictum (Event): A formal pronouncement or decree. It is published to multiple handlers (zero or more) to notify other parts of the system that something has happened.
    • IDictum: The marker interface for all dicta.

Installation

The easiest way to add PraetoR to your project is via the NuGet package manager.

dotnet add package PraetoR

Getting Started

Let's walk through a complete flow: a command to create a user and a dictum to notify other parts of the system about this creation.

1. Define your Commands and Dicta

Create classes that represent the operations and events in your system.

CreateUserCommand.cs (A command that returns the ID of the new user)

using PraetoR.Abstractions;

public class CreateUserCommand : IOperation<Guid>
{
    public string UserName { get; }
    public CreateUserCommand(string userName) => UserName = userName;
}

UserCreatedDictum.cs (A dictum that carries information about the created user)

using PraetoR.Abstractions;

public class UserCreatedDictum : IDictum
{
    public Guid UserId { get; }
    public UserCreatedDictum(Guid userId) => UserId = userId;
}

2. Implement Handlers

Create classes that contain the logic to process your commands and dicta.

CreateUserCommandHandler.cs

using PraetoR.Abstractions;

public class CreateUserCommandHandler : IOperation Handler<CreateUserCommand, Guid>
{
    private readonly IUserRepository _userRepository;
    private readonly IPraetoR _PraetoR;

    public CreateUserCommandHandler(IUserRepository userRepository, IPraetoR PraetoR)
    {
        _userRepository = userRepository;
        _PraetoR = PraetoR;
    }

    public async Task<Guid> Handle(CreateUserCommand command, CancellationToken cancellationToken)
    {
        // Business logic to create the user...
        var newUser = new User { Name = command.UserName };
        var newUserId = await _userRepository.Add(newUser);

        // Publishes a dictum to notify other parts of the system
        await _PraetoR.Publish(new UserCreatedDictum(newUserId), cancellationToken);

        return newUserId;
    }
}

SendWelcomeEmailHandler.cs (A handler that reacts to the dictum)

using PraetoR.Abstractions;

public class SendWelcomeEmailHandler : IDictumHandler<UserCreatedDictum>
{
    public Task Handle(UserCreatedDictum dictum, CancellationToken cancellationToken)
    {
        Console.WriteLine($"Sending welcome email to user {dictum.UserId}...");
        // Email sending logic goes here...
        return Task.CompletedTask;
    }
}

3. Register PraetoR with Dependency Injection

In your Program.cs (or Startup.cs), call the AddPraetoR extension method, specifying which assembly it should scan to find your handlers.

Program.cs

using System.Reflection;
using PraetoR.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Registers PraetoR and all handlers in the current assembly
builder.Services.AddPraetoR(Assembly.GetExecutingAssembly());

// ... register your other dependencies, like IUserRepository
// builder.Services.AddScoped<IUserRepository, UserRepository>();

var app = builder.Build();
// ...

4. Use IPraetoR to Dispatch

Now, in your classes (like API controllers), you can inject IPraetoR and use it to send commands, keeping your code clean and decoupled from the business logic.

UsersController.cs

using Microsoft.AspNetCore.Mvc;
using PraetoR.Abstractions;

[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
    private readonly IPraetoR _PraetoR;

    public UsersController(IPraetoR PraetoR)
    {
        _PraetoR = PraetoR;
    }

    [HttpPost]
    public async Task<IActionResult> CreateUser([FromBody] CreateUserRequest request)
    {
        var command = new CreateUserCommand(request.UserName);
        var newUserId = await _PraetoR.Send(command); // Send the command
        
        return Ok(new { Id = newUserId });
    }
}

API Overview

Interface Description
IPraetoR The central dispatcher for sending commands and publishing dicta.
IOperation<TResult> Represents a command that expects a response of type TResult.
IOperation Represents a command that executes an action but returns no value.
IOperationHandler<...> Defines the class that handles an IOperation.
IDictum A marker interface for events (dicta) that can be published.
IDictumHandler<TDictum> Defines the class that handles (listens for) an IDictum.

Contributing

Contributions are welcome! If you find a bug or have a suggestion for an improvement, feel free to open an issue or submit a Pull Request.

License

This project is licensed under the MIT License. See the LICENSE file for more details.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on PraetoR:

Package Downloads
PraetoR.FluentValidation

PraetoR is a lightweight .NET library that acts as a central dispatcher for commands and events. It allows you to decouple business logic, resulting in a more organized, testable, and maintainable architecture that follows the principles of CQRS and event-driven design.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1-alpha 57 9/27/2025
1.0.0-alpha 123 9/25/2025