DioRed.CoIn 0.1.1

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

<p> <img src="assets/coin-wide-logo.png" alt="CoIn Logo"/> </p>

CoIn (Command Invoker) is a lightweight framework for organizing application logic through commands and their handlers.

DioRed.CoIn

Lightweight command invocation framework.
Alternative to MediatR with synchronous and asynchronous handler support + fallback.


Install

dotnet add package DioRed.CoIn

Define commands

With result:

public record CreateUser(string Name, string Email) : ICommand<Guid>;

Without result:

public record SendEmail(string To, string Subject, string Body) : ICommand;

Create handlers

Synchronous:

public class CreateUserHandler : ICommandHandler<CreateUser, Guid>
{
    public Guid Handle(CreateUser command)
    {
        Console.WriteLine($"Creating user: {command.Name} ({command.Email})");
        return Guid.NewGuid();
    }
}

public class SendEmailHandler : ICommandHandler<SendEmail>
{
    public void Handle(SendEmail command)
    {
        Console.WriteLine($"Sending email to {command.To}: {command.Subject}");
    }
}

Asynchronous:

public class CreateUserAsyncHandler : IAsyncCommandHandler<CreateUser, Guid>
{
    public async Task<Guid> HandleAsync(CreateUser command, CancellationToken ct)
    {
        await Task.Delay(100, ct); // fake async work
        Console.WriteLine($"[Async] Creating user: {command.Name} ({command.Email})");
        return Guid.NewGuid();
    }
}

public class SendEmailAsyncHandler : IAsyncCommandHandler<SendEmail>
{
    public async Task HandleAsync(SendEmail command, CancellationToken ct)
    {
        await Task.Delay(50, ct);
        Console.WriteLine($"[Async] Sending email to {command.To}: {command.Subject}");
    }
}

Register handlers

In Program.cs:

using DioRed.CoIn;

builder.Services.AddCoIn(typeof(CreateUser).Assembly);

AddCoIn will:

  • Register all handlers from the given assemblies
  • Register a singleton IInvoker for invoking commands

Use the invoker

public class UserService
{
    private readonly IInvoker _invoker;

    public UserService(IInvoker invoker) => _invoker = invoker;

    public Guid CreateUserSync(string name, string email)
    {
        var cmd = new CreateUser(name, email);
        return _invoker.Invoke(cmd);
        // Uses sync handler if available
        // Otherwise async handler executed via GetAwaiter().GetResult()
    }

    public async Task<Guid> CreateUserAsync(string name, string email, CancellationToken ct)
    {
        var cmd = new CreateUser(name, email);
        return await _invoker.InvokeAsync(cmd, ct);
        // Prefers async handler
        // Falls back to sync handler wrapped into Task.FromResult
    }

    public void SendEmail(string to, string subject, string body)
    {
        var cmd = new SendEmail(to, subject, body);
        _invoker.Invoke(cmd);
    }

    public Task SendEmailAsync(string to, string subject, string body, CancellationToken ct)
    {
        var cmd = new SendEmail(to, subject, body);
        return _invoker.InvokeAsync(cmd, ct);
    }
}

Fallbacks

  • Calling Invoke(...) with only an async handler → framework executes it synchronously
  • Calling InvokeAsync(...) with only a sync handler → framework wraps result into a completed task

So the caller never needs to care which handler type is actually registered.


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 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

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
0.1.1 199 8/30/2025
0.1.0 183 8/29/2025