Xin.Medius is a .NET library which implements the Mediator pattern.
There are a number of public and popular Mediator libraries available, Xin.Medius differentiates itself from those in the goals of it’s implementation. The goals for Xin.Medius are:
- Simplicity
The implementation should be simple to navigate and debug.
- Explicit (no magic)
There should be no “magic” involved which leads you to guessing what the compiler has done; for example assembly scanning.
Handler registrations should be verbose.
Return types should be clear on the line which invokes a request.
- Safety
There should be as little type coersion as possible.
This has lead to a design which strongly types the Request and RequestHandlers, and enables fewer layers of abstraction in service location. In our opinion, this leads to an overall cleaner design, dispite additional verbosity.
Example
// Request specification
public record SomeRequest(string Message) : IRequest<string>;
// RequestHandler specification
public class SomeRequestHandler : IRequestHandler<SomeRequest, string>
{
public Task<string> HandleAsync(SomeRequest request, CancellationToken cancellationToken)
{
string response = "This is an example";
return Task.FromResult(response);
}
}
// Registration
public static IServiceCollection InjectMediator(this IServiceCollection services)
{
// Register the mediator using a builder, and associate requests to handlers
services.AddSingleton<Mediator>(provider =>
new MediatorRegistryBuilder()
.Register<SomeRequest, string>(typeof(SomeRequestHandler))
.Build());
// Register the handler(s)
services.AddTransient<SomeRequestHandler>();
return services;
}
// Invocation
class App
{
private readonly Mediator mediator;
private readonly CancellationTokenSource cts = new ();
public App(Mediator mediator)
{
this.mediator = mediator;
}
public async Task DoSomething()
{
var response = await this.mediator.Send<SomeRequest, string>(
new SomeRequest("I'm doing something"), this.cts.Token);
}
}