Eml.Mediator
10.1.1
dotnet add package Eml.Mediator --version 10.1.1
NuGet\Install-Package Eml.Mediator -Version 10.1.1
<PackageReference Include="Eml.Mediator" Version="10.1.1" />
<PackageVersion Include="Eml.Mediator" Version="10.1.1" />
<PackageReference Include="Eml.Mediator" />
paket add Eml.Mediator --version 10.1.1
#r "nuget: Eml.Mediator, 10.1.1"
#:package Eml.Mediator@10.1.1
#addin nuget:?package=Eml.Mediator&version=10.1.1
#tool nuget:?package=Eml.Mediator&version=10.1.1
Eml.Mediator
Has own Visual Studio Addin for easier use.
Small size.
Capture Business-use-cases and convert it into a modular, highly testable chunk of codes. One step closer to dissecting & migrating monolithic apps. A combination of Command, Request-Response, Mediator and Abstract Class Factory pattern.
Provides a common ground for projects with large number of developers.
.Net5 is now supported.
Features
ExecuteAsync will always create a new instance of the handler.
The lifetime of the handler ends as soon as ExecuteAsync is completed.
If this behavior does not suit your needs, just use dependency injection via the constructor. See example DI signature below:
IRequestAsyncHandler<TestAsyncRequest, TestResponse> testRequestAsyncHandler
A. Usage - Command
[Fact]
public async Task Command_ShouldBeCalledOnce()
{
var command = new TestAsyncCommand(); //<-Data
await mediator.ExecuteAsync(command); //<-Execute
command.HandlerInvocationCount.ShouldBe(1);
}
1. Create a command class.
TestAsyncCommand contains the needed data for await mediator.ExecuteAsync(command);.
public class TestAsyncCommand : ICommandAsync
{
public int HandlerInvocationCount { get; set; }
/// <summary>
/// This request will be processed by <see cref="TestAsyncCommandHandler"/>.
/// </summary>
public TestAsyncCommand()
{
HandlerInvocationCount = 0;
}
}
2. Create a command handler.
TestAsyncCommandHandler will be auto-discovered and executed by await mediator.ExecuteAsync(command);.
/// <summary>
/// DI signature: ICommandAsyncHandler<TestAsyncCommand>.
/// <inheritdoc cref="ICommandAsyncHandler{TestAsyncCommand}"/>
/// </summary>
public class TestAsyncCommandHandler : ICommandAsyncHandler<TestAsyncCommand>
{
public async Task ExecuteAsync(TestAsyncCommand commandAsync)
{
await Task.Run(() => commandAsync.HandlerInvocationCount++);
}
}
B. Usage - Request-Response
[Fact]
public async Task Response_ShouldReturnCorrectValue()
{
var request = new TestAsyncRequest(Guid.CreateVersion7()); //<-Request
var response = await mediator.ExecuteAsync(request); //<-Execute
response.ResponseToRequestId.ShouldBe(request.Id); //<-Return Value
}
1. Create a Request class.
TestAsyncRequest contains the needed data for TestRequestAsyncHandler.
public class TestAsyncRequest : IRequestAsync<TestAsyncRequest, TestResponse>
{
public Guid Id { get; private set; }
/// <summary>
/// This request will be processed by <see cref="TestRequestAsyncHandler"/>.
/// </summary>
public TestAsyncRequest(Guid id)
{
Id = id;
}
}
2. Create a Response class.
TestResponse is the return value of await mediator.ExecuteAsync(request);.
/// <summary>
/// TestRequestAsyncHandler return value.
/// </summary>
public class TestResponse : IResponse
{
public Guid ResponseToRequestId { get; } //<-Return Value
public TestResponse(Guid responseToRequestId)
{
ResponseToRequestId = responseToRequestId;
}
}
3. Create a Request handler.
TestRequestAsyncHandler will be auto-discovered and executed by var response = await mediator.ExecuteAsync(request);.
/// <summary>
/// DI signature: IRequestAsyncHandler<TestAsyncRequest, TestResponse>.
/// <inheritdoc cref="IRequestAsyncHandler{TestAsyncRequest, TestResponse}"/>
/// </summary>
public class TestRequestAsyncHandler : IRequestAsyncHandler<TestAsyncRequest, TestResponse>
{
public async Task<TestResponse> ExecuteAsync(TestAsyncRequest request)
{
return await Task.Run(() => new TestResponse(request.Id));
}
}
C. DI Registration
Requires Scrutor for the automated registration.
See IntegrationTestDiFixture.cs for more details.
private static void ConfigureServices(IServiceCollection services)
{
services.Scan(scan => scan
.FromAssemblyDependencies(typeof(IntegrationTestDiFixture).Assembly)
// Register IMediator
.AddClasses(classes => classes.AssignableTo<IMediator>())
.AsSelfWithInterfaces()
.WithSingletonLifetime()
// Register RequestHandlers, CommandHandlers - Async
.AddClasses(classes => classes.AssignableTo(typeof(IRequestAsyncHandler<,>)))
.AsImplementedInterfaces()
.WithTransientLifetime()
// Register RequestHandlers, CommandHandlers
.AddClasses(classes => classes.AssignableTo(typeof(IRequestHandler<,>)))
.AsImplementedInterfaces()
.WithTransientLifetime()
// Register CommandHandlers - Async
.AddClasses(classes => classes.AssignableTo(typeof(ICommandAsyncHandler<>)))
.AsImplementedInterfaces()
.WithTransientLifetime()
// Register CommandHandlers
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<>)))
.AsImplementedInterfaces()
.WithTransientLifetime()
// IDiDiscoverableTransient
.AddClasses(classes => classes.AssignableTo(typeof(IDiDiscoverableTransient)))
.AsImplementedInterfaces()
.WithTransientLifetime()
);
}
D. Sample Class
- Simply inject IMediator in the constructor. See ConsumerClassWithMediator.cs for more details.
public class ConsumerClassWithMediator : IConsumerClassWithMediator
{
private readonly IMediator mediator;
public ConsumerClassWithMediator(IMediator mediator) //<-Inject IMediator
{
this.mediator = mediator;
}
public async Task<TestResponse> DoSomething()
{
var request = new TestAsyncRequest(Guid.CreateVersion7()); //<-Request
var response = await mediator.ExecuteAsync(request); //<-Execute
return response; //<-Return Value
}
}
- This is the equivalent class without leveraging IMediator. See ConsumerClassWithoutMediator.cs for more details.
public class ConsumerClassWithoutMediator : IConsumerClassWithoutMediator
{
private readonly IRequestAsyncHandler<TestAsyncRequest, TestResponse> handler;
public ConsumerClassWithoutMediator(IRequestAsyncHandler<TestAsyncRequest, TestResponse> handler) //<-Normal dependency injection. Inject handler
{
this.handler = handler;
}
public async Task<TestResponse> DoSomething()
{
var request = new TestAsyncRequest(Guid.CreateVersion7()); //<-Request
var response = await handler.ExecuteAsync(request); //<-Execute
return response; //<-Return Value
}
}
That's it.
Check out Eml.Mediator.vsix to automate the steps above.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- Microsoft.Extensions.DependencyInjection (>= 10.0.8)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Eml.Mediator:
| Package | Downloads |
|---|---|
|
Eml.ControllerBase
ControllerBase for WebApi CRUD operations. |
|
|
Eml.ControllerBase.Mvc
Base Classes for MVC CRUD operations and other useful utilities. |
|
|
Eml.ControllerBase.Api.MySql
ControllerBase for WebApi with MySql. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.1.1 | 119 | 5/28/2026 |
| 8.0.0 | 5,523 | 11/26/2023 |
| 7.1.2 | 1,967 | 9/3/2023 |
| 7.1.1 | 1,515 | 7/8/2023 |
| 7.1.0 | 1,469 | 7/1/2023 |
| 7.0.0 | 1,722 | 12/10/2022 |
| 6.0.3 | 1,867 | 8/27/2022 |
| 6.0.2 | 1,790 | 8/27/2022 |
| 6.0.0 | 3,086 | 1/19/2022 |
| 5.0.8 | 1,831 | 9/17/2021 |
| 5.0.7 | 1,902 | 3/16/2021 |
| 5.0.6 | 2,083 | 2/28/2021 |
| 5.0.0 | 2,268 | 1/16/2021 |