Source generator based mediator implementation without the reflection AOTable
.
Supports action dispatch and subscribe.
Install-Package SourceGeneration.ActionDispatcher -Version 1.0.0-beta1.240217.1
dotnet add package SourceGeneration.ActionDispatcher --version 1.0.0-beta1.240217.1
services.AddActionDispatcher()
public class Say
{
public string? Text { get; set; }
}
You just need add ActionHandlerAttribute
to method
public class ActionHandler
{
[ActionHandler]
public void Handle(Say say, ILogger<ActionHandler> logger, CancellationToken cancellationToken)
{
logger.LogInformation("Handled : " + say.Text);
}
[ActionHandler]
public static void StaticHandle(Say say, ILogger<ActionHandler> logger, CancellationToken cancellationToken)
{
logger.LogInformation("StaticHandle : " + say.Text);
}
[ActionHandler]
public async Task AsyncHandle(Say say, ILogger<ActionHandler> logger, CancellationToken cancellationToken)
{
await Task.Delay(1000, cancellationToken);
logger.LogInformation("AsyncHandled : " + say.Text);
}
}
Method parameters follow the following rules
- The first parameter must be your
action
message
commond
event
CancellationToken
is passed from the caller- Other parameters come from dependency injection
First, the ActionDispatcher will check the IServiceProvider to see if the ActionHandler has been added to the container. If it has, it will be obtained through dependency injection. Otherwise, a new ActionHandler will be created.
public class InjectServiceHandler(ILogger<InjectServiceHandler> logger)
{
[ActionHandler]
public void Handle(Say say)
{
logger.LogInformation("InjectServiceHandled : " + say.Text);
}
}
services.AddSingleton<InjectServiceHandler>();
You can dispatch action with IActionDispatcher
var dispatcher = services.GetRequiredService<IActionDispatcher>();
dispatcher.Dispatch(new Say { Say = "Hello World" });
Asynchronous invocation is supported.
await dispatcher.DispatchAsync(new Say { Say = "Hello World" });
Log console output
info: ActionHandler[0]
StaticHandle : Hello World
info: ActionHandler[0]
Handled : Hello World
info: InjectServiceHandler[0]
InjectServiceHandled : Hello World
info: ActionHandler[0]
AsyncHandled : Hello World
You can subscribe action with IActionSubscriber
, supprots ActionDispatchStatus
:
- ActionDispatchStatus.WaitingToDispatch
- ActionDispatchStatus.Canceld
- ActionDispatchStatus.Successed
- ActionDispatchStatus.Faulted
var subscriber = services.GetRequiredService<IActionSubscriber>();
subscriber.Subscribe<Say>(action =>
{
Console.WriteLine("Subscriber: Say action dispatched.");
});
subscriber.Subscribe<Say>(ActionDispatchStatus.WaitingToDispatch, action =>
{
Console.WriteLine("Subscriber: Say action dispatching.");
});
subscriber.Subscribe<Say>(ActionDispatchStatus.Faulted, (action, exception) =>
{
Console.WriteLine("Subscriber: Say action dispatch faulted.");
});
//Subscribe all types action
subscriber.Subscribe<object>(action =>
{
Console.WriteLine($"Subscriber: {action.GetType()} action dispatched");
});