PulseFlow 1.2.0

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

PulseFlow Banner

PulseFlow

NuGet Version License

Lightweight, dependency-free primitives for implementing Clean Architecture, Domain-Driven Design (DDD), and CQRS in .NET applications.

Overview

PulseFlow provides a small, focused set of abstractions designed to simplify the modeling of domain-centered applications without introducing infrastructure or framework dependencies. It aims to be a high-performance, foundational library for building robust and scalable systems.

Key Features:

  • Minimal & Focused: A small, well-documented API surface.
  • Framework-Agnostic: Suitable for various application types (web, serverless, desktop, worker apps).
  • Dependency-Free: No external runtime dependencies, ensuring a lean footprint.
  • High Performance: Optimized Mediator implementation using wrapper patterns and caching for efficient command/query dispatch.
  • Testability: Designed for easy unit testing and composition.
  • Modern .NET: Compatible with .NET 8 and later.

Included Primitives:

  • Result / Result<T>: For explicit error handling and success/failure representation.
  • Entity<TId>: Base class for domain entities with identity.
  • AggregateRoot<TId>: Base class for DDD aggregate roots, extending Entity.
  • ValueObject: Base class for implementing value objects.
  • DomainEvent: Base class for domain events.
  • ICommand, IQuery, INotification: Interfaces for CQRS messages.
  • ICommandHandler<TCommand>, IQueryHandler<TQuery, TResult>, INotificationHandler<TNotification>: Interfaces for handling CQRS messages.
  • IMediator: Interface for dispatching commands, queries, and notifications.
  • IPipelineBehavior<TRequest, TResponse>: For cross-cutting concerns in the Mediator pipeline.

These building blocks are intentionally minimal and designed to be composed into larger architectures (microservices, monoliths, event-driven systems, serverless functions, etc.).

Installation

Install the package from NuGet:

dotnet add package PulseFlow

Quick Examples

Result Usage:

var result = Result.Ok();
if (result.IsFailure) Console.WriteLine(result.Error);

var userResult = Result<string>.Ok("User created successfully!");

Entity / AggregateRoot:

public class User : Entity<Guid>
{
    public string Email { get; }

    public User(Guid id, string email) : base(id)
    {
        Email = email;
    }
}

public class Order : AggregateRoot<Guid>
{
    public Order(Guid id) : base(id) { }
}

Value Object:

public class Email : ValueObject
{
    public string Value { get; }

    public Email(string value) => Value = value;

    protected override IEnumerable<object> GetEqualityComponents()
    {
        yield return Value;
    }
}

Commands / Queries and Handlers:

// Define a Command and its Handler
public record CreateUserCommand(string Email) : ICommand;

public class CreateUserHandler : ICommandHandler<CreateUserCommand>
{
    public Task<Result> Handle(CreateUserCommand command, CancellationToken ct)
    {
        // Domain logic to create a user...
        Console.WriteLine($"Creating user with email: {command.Email}");
        return Task.FromResult(Result.Ok());
    }
}

// Define a Query and its Handler
public record GetUserQuery(Guid Id) : IQuery<User>;

public class GetUserHandler : IQueryHandler<GetUserQuery, User>
{
    public Task<Result<User>> Handle(GetUserQuery query, CancellationToken ct)
    {
        // Logic to retrieve a user...
        var user = new User(query.Id, "test@mail.com");
        return Task.FromResult(Result<User>.Ok(user));
    }
}

Mediator Usage and Setup:

First, register the Mediator, the pipeline behaviors you need (for example validation), and your handlers/validators in your Program.cs or Startup.cs:

using PulseFlow.Application.Mediator;
using PulseFlow.Application.Validation;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        // Register pipeline behaviors (e.g. validation)
        builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));

        // Register Mediator and scan for handlers (and validators) in the current assembly
        // This overload accepts assemblies: services.AddMediator(Assembly.GetExecutingAssembly())
        builder.Services.AddMediator(Assembly.GetExecutingAssembly());

        // Or to scan all loaded assemblies:
        // builder.Services.AddMediator();

        // Alternatively, register validators manually if you don't want automatic discovery:
        // builder.Services.AddTransient<IValidator<CreateUserCommand>, CreateUserCommandValidator>();

        var app = builder.Build();

        // Example usage:
        app.Run(async (context) =>
        {
            var mediator = context.RequestServices.GetRequiredService<IMediator>();

            // Sending a Command
            var commandResult = await mediator.Send(new CreateUserCommand("new.user@example.com"));
            if (commandResult.IsSuccess)
            {
                await context.Response.WriteAsync("Command executed successfully!");
            }
            else
            {
                await context.Response.WriteAsync($"Command failed: {commandResult.Error}");
            }

            // Sending a Query
            var queryResult = await mediator.Send(new GetUserQuery(Guid.NewGuid()));
            if (queryResult.IsSuccess)
            {
                await context.Response.WriteAsync($"\nQuery executed successfully! User: {queryResult.Value.Email}");
            }
            else
            {
                await context.Response.WriteAsync($"\nQuery failed: {queryResult.Error}");
            }
        });

        app.Run();
    }
}

Notes

  • The AddMediator(Assembly...) overload scans the specified assemblies and registers discovered ICommandHandler<>, IQueryHandler<,> and (in this library version) implementations of IValidator<> so they can be resolved by the ValidationBehavior.
  • The parameterless AddMediator() overload scans all currently loaded assemblies.
  • You still need to register the pipeline behaviors you want to run in the pipeline (for example ValidationBehavior). If you prefer, you can register validators manually instead of relying on automatic discovery.

Design Principles

  • Single-Responsibility: Small, focused API surface for each primitive.
  • No External Dependencies: Ensures a lightweight and flexible core.
  • Predictable Behavior: Explicit Result types for clear success/failure outcomes.
  • High Performance: Optimized Mediator dispatch for minimal overhead.
  • Testability & Composition: Designed for easy unit testing and integration into complex systems.

Roadmap

  • Pipeline Behaviors: Built-in support for logging, validation, and metrics.
  • Async Domain Event Dispatcher: Enhanced event handling capabilities.
  • Notification Pattern: Improved handling of side effects and notifications.
  • Optional Integrations: (e.g., Redis, Kafka, RabbitMQ) for advanced scenarios.
  • Source Generators: To further reduce boilerplate code.

Contributing

Contributions, issues, and pull requests are welcome! Please follow these guidelines:

  • Open an issue to discuss non-trivial changes before implementing.
  • Keep changes small and focused.
  • Add unit tests for new behavior and bug fixes.

Support

This project is developed and maintained by Andrés Mariño. If you find this library useful and would like to support its continued development, you can buy me a coffee!

Bitcoin (BTC): bc1p9zqgxghkjhauruhsza9n382e6kp5tpj4xtzu2csv4mypsdtdc4tqvdyg86 Buy Me a Coffee at Ko-fi

License

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

Product 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 is compatible.  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

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
1.2.0 53 5/29/2026
1.1.0 75 5/28/2026
1.0.0 67 5/27/2026

- Adding FluentValidationBejavior
           - Automatic discovery and registration of `IValidator<T>` implementations when using `AddMediator(Assembly...)`, so validators discovered in scanned assemblies are registered into DI and can be resolved by `ValidationBehavior`.
           - Documentation: Updated README to show how to register `ValidationBehavior` as an `IPipelineBehavior<TRequest, TResponse>` and to document the `AddMediator(Assembly...)` overload and the automatic validator discovery behavior.