Source generator based mediator implementation without the reflection AOTable.
Supports action dispatch and subscribe.
Install-Package SourceGeneration.ActionDispatcher -Version 1.0.0dotnet add package SourceGeneration.ActionDispatcher --version 1.0.0services.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
actionmessagecommondevent CancellationTokenis 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 WorldYou 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");
});