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
<PackageReference Include="Simplify.Bus.Impl" Version="0.1.3" />
<PackageVersion Include="Simplify.Bus.Impl" Version="0.1.3" />
<PackageReference Include="Simplify.Bus.Impl" />
paket add Simplify.Bus.Impl --version 0.1.3
#r "nuget: Simplify.Bus.Impl, 0.1.3"
#:package Simplify.Bus.Impl@0.1.3
#addin nuget:?package=Simplify.Bus.Impl&version=0.1.3
#tool nuget:?package=Simplify.Bus.Impl&version=0.1.3
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 | Versions 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. |
-
.NETStandard 2.0
- Simplify.Bus (>= 0.1.0)
- Simplify.DI (>= 4.3.0)
-
net10.0
- Simplify.Bus (>= 0.1.0)
- Simplify.DI (>= 4.3.0)
-
net6.0
- Simplify.Bus (>= 0.1.0)
- Simplify.DI (>= 4.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.