Simplify.Bus.Impl 0.1.3

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

Simplify.Bus Documentation

A lightweight, async-first message bus implementing the mediator pattern. It supports three messaging styles:

  • Commands — a fire-and-forget request handled by a single handler.
  • Queries — a request handled by a single handler that returns a response.
  • Events — a notification published to multiple handlers.

In addition, a behavior pipeline allows middleware-style interceptors (validation, logging, etc.) to wrap request handling.

All operations are Task-based.

Abstractions are available at NuGet as binary package. The implementation and Simplify.DI integration are in Simplify.Bus.Impl.

Core types

All abstractions live in the Simplify.Bus namespace; the implementations and DI registration extensions live in Simplify.Bus.Impl.

Concept Bus interface Handler interface Dispatch method Handlers per message
Command (no response) IBusAsync<TRequest> IRequestHandler<TRequest> Task Send(TRequest request) 1
Query (with response) IBusAsync<TRequest, TResponse> IRequestHandler<TRequest, TResponse> Task<TResponse> Send(TRequest request) 1
Event IEventBusAsync<TEvent> IEventHandler<TEvent> Task Publish(TEvent busEvent) many

Handler method signatures:

// IRequestHandler<TRequest>
Task Handle(TRequest request);

// IRequestHandler<TRequest, TResponse>
Task<TResponse> Handle(TRequest request);

// IEventHandler<TEvent>
Task Handle(TEvent busEvent);

Commands (fire-and-forget)

Define a request and its handler:

using Simplify.Bus;

public class CreateUserCommand(IUser user)
{
    public IUser User { get; } = user;
}

public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand>
{
    public Task Handle(CreateUserCommand command)
    {
        // ... create the user
        return Task.CompletedTask;
    }
}

Register and dispatch:

using Simplify.DI;
using Simplify.Bus;
using Simplify.Bus.Impl;

DIContainer.Current
    .Register<IRequestHandler<CreateUserCommand>, CreateUserCommandHandler>()
    .RegisterBus<CreateUserCommand>();

using var scope = DIContainer.Current.BeginLifetimeScope();

var bus = scope.Resolver.Resolve<IBusAsync<CreateUserCommand>>();
await bus.Send(new CreateUserCommand(user));

Queries (request with response)

using Simplify.Bus;

public class GetUserQuery(int userId)
{
    public int UserId { get; } = userId;
}

public class GetUserResponse(IUser? user)
{
    public IUser? User { get; } = user;
}

public class GetUserQueryHandler(IUsersRepository repository)
    : IRequestHandler<GetUserQuery, GetUserResponse>
{
    public async Task<GetUserResponse> Handle(GetUserQuery request) =>
        new GetUserResponse(await repository.GetAsync(request.UserId));
}
DIContainer.Current
    .Register<IRequestHandler<GetUserQuery, GetUserResponse>, GetUserQueryHandler>()
    .RegisterBus<GetUserQuery, GetUserResponse>();

using var scope = DIContainer.Current.BeginLifetimeScope();

var bus = scope.Resolver.Resolve<IBusAsync<GetUserQuery, GetUserResponse>>();
var response = await bus.Send(new GetUserQuery(1));

Events (publish to multiple handlers)

An event can have any number of handlers:

using Simplify.Bus;

public class UserCreatedEvent(IUser user)
{
    public IUser User { get; } = user;
}

public class SendWelcomeEmailHandler : IEventHandler<UserCreatedEvent>
{
    public Task Handle(UserCreatedEvent busEvent) { /* ... */ return Task.CompletedTask; }
}

public class AuditUserCreationHandler : IEventHandler<UserCreatedEvent>
{
    public Task Handle(UserCreatedEvent busEvent) { /* ... */ return Task.CompletedTask; }
}
DIContainer.Current
    .Register<SendWelcomeEmailHandler>()
    .Register<AuditUserCreationHandler>()
    .RegisterEventBus<UserCreatedEvent>(
        typeof(SendWelcomeEmailHandler),
        typeof(AuditUserCreationHandler));

using var scope = DIContainer.Current.BeginLifetimeScope();

var bus = scope.Resolver.Resolve<IEventBusAsync<UserCreatedEvent>>();
await bus.Publish(new UserCreatedEvent(user));

Publish strategy

The order/error handling of event handlers is controlled by the PublishStrategy enum:

  • SyncStopOnException (default) — handlers run sequentially and publishing stops on the first exception.
  • ParallelWhenAll — all handlers run in parallel and exceptions are aggregated.

Pass the strategy as the first argument when registering the event bus:

DIContainer.Current
    .Register<SendWelcomeEmailHandler>()
    .Register<AuditUserCreationHandler>()
    .RegisterEventBus<UserCreatedEvent>(
        PublishStrategy.ParallelWhenAll,
        typeof(SendWelcomeEmailHandler),
        typeof(AuditUserCreationHandler));

Behaviors (middleware pipeline)

Behaviors wrap request handling, receiving the request and a next delegate that invokes the next behavior (or finally the handler).

using Simplify.Bus;

// For commands (no response)
public class LoggingBehavior<TRequest> : IBehavior<TRequest>
{
    public Task Handle(TRequest request, RequestHandler next)
    {
        // pre-processing
        return next();
        // post-processing could await next() then continue
    }
}

// For queries (with response)
public class ValidationBehavior : IBehavior<GetUserQuery, GetUserResponse>
{
    public Task<GetUserResponse> Handle(GetUserQuery request, RequestHandler<GetUserResponse> next)
    {
        // validate request...
        return next();
    }
}

The next parameters are the delegates public delegate Task RequestHandler(); and public delegate Task<TResponse> RequestHandler<TResponse>();.

Behaviors are passed to RegisterBus and execute in the order listed (behavior1 → behavior2 → handler):

DIContainer.Current
    .Register<IRequestHandler<CreateUserCommand>, CreateUserCommandHandler>()
    .Register<LoggingBehavior<CreateUserCommand>>()
    .Register<CreateUserCommandValidationBehavior>()
    .RegisterBus<CreateUserCommand>(
        typeof(LoggingBehavior<CreateUserCommand>),
        typeof(CreateUserCommandValidationBehavior));

DI registration reference

The Simplify.Bus.Impl namespace provides these IDIRegistrator extension methods:

// Commands
IDIRegistrator RegisterBus<TRequest>(this IDIRegistrator registrator, params Type[] behaviors);

// Queries
IDIRegistrator RegisterBus<TRequest, TResponse>(this IDIRegistrator registrator, params Type[] behaviors);

// Events
IDIRegistrator RegisterEventBus<TEvent>(this IDIRegistrator registrator, params Type[] eventHandlers);
IDIRegistrator RegisterEventBus<TEvent>(this IDIRegistrator registrator, PublishStrategy publishStrategy, params Type[] eventHandlers);

These register the corresponding IBusAsync<...> / IEventBusAsync<...> implementation. You must register the request handlers, event handlers, and behaviors themselves separately (as shown in the examples above).

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  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 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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  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

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.3 57 6/25/2026
0.1.2 202 10/11/2025
0.1.1 697 6/21/2022
0.1.0 627 5/24/2022