{"id":26766184,"url":"https://github.com/sourcegeneration/actiondispatcher","last_synced_at":"2025-03-28T20:19:25.304Z","repository":{"id":212804168,"uuid":"731607167","full_name":"SourceGeneration/ActionDispatcher","owner":"SourceGeneration","description":"Source generator based mediator implementation without reflection. Supports action dispatch and subscribe.","archived":false,"fork":false,"pushed_at":"2025-03-02T06:53:15.000Z","size":66,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-02T07:27:57.459Z","etag":null,"topics":["actiondispatcher","aot","command","csharp","dispatcher","dotnet","event","mediator","sourcegenerator","subscriber"],"latest_commit_sha":null,"homepage":"https://github.com/SourceGeneration/ActionDispatcher","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SourceGeneration.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-14T13:10:44.000Z","updated_at":"2025-03-02T06:53:18.000Z","dependencies_parsed_at":"2023-12-19T15:56:48.389Z","dependency_job_id":"fd066b36-936b-48d7-9dd0-e04209da1cc6","html_url":"https://github.com/SourceGeneration/ActionDispatcher","commit_stats":null,"previous_names":["sourcegeneration/actiondispatcher"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SourceGeneration%2FActionDispatcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SourceGeneration%2FActionDispatcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SourceGeneration%2FActionDispatcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SourceGeneration%2FActionDispatcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SourceGeneration","download_url":"https://codeload.github.com/SourceGeneration/ActionDispatcher/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246093166,"owners_count":20722403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actiondispatcher","aot","command","csharp","dispatcher","dotnet","event","mediator","sourcegenerator","subscriber"],"created_at":"2025-03-28T20:19:24.730Z","updated_at":"2025-03-28T20:19:25.292Z","avatar_url":"https://github.com/SourceGeneration.png","language":"C#","readme":"# ActionDispatcher\n\n[![NuGet](https://img.shields.io/nuget/vpre/SourceGeneration.ActionDispatcher.svg)](https://www.nuget.org/packages/SourceGeneration.ActionDispatcher)\n\nSource generator based mediator implementation without the reflection `AOTable`. \nSupports action dispatch and subscribe.\n\n## Installing ActionDispatcher\n\n```powershell\nInstall-Package SourceGeneration.ActionDispatcher -Version 1.0.0-beta1.240217.1\n```\n\n```powershell\ndotnet add package SourceGeneration.ActionDispatcher --version 1.0.0-beta1.240217.1\n```\n\n## Registering with IServiceCollection\n\n```c#\nservices.AddActionDispatcher()\n```\n\n## `Action` or `Message` or `Command` or `Event`\n\n```c#\npublic class Say\n{\n    public string? Text { get; set; }\n}\n```\n\n## Handler\n\nYou just need add `ActionHandlerAttribute` to method\n```c#\npublic class ActionHandler\n{\n    [ActionHandler]\n    public void Handle(Say say, ILogger\u003cActionHandler\u003e logger, CancellationToken cancellationToken)\n    {\n        logger.LogInformation(\"Handled : \" + say.Text);\n    }\n\n    [ActionHandler]\n    public static void StaticHandle(Say say, ILogger\u003cActionHandler\u003e logger, CancellationToken cancellationToken)\n    {\n        logger.LogInformation(\"StaticHandle : \" + say.Text);\n    }\n\n    [ActionHandler]\n    public async Task AsyncHandle(Say say, ILogger\u003cActionHandler\u003e logger, CancellationToken cancellationToken)\n    {\n        await Task.Delay(1000, cancellationToken);\n        logger.LogInformation(\"AsyncHandled : \" + say.Text);\n    }\n}\n```\nMethod parameters follow the following rules\n- The first parameter must be your `action` `message` `commond` `event`\n- `CancellationToken` is passed from the caller\n- Other parameters come from dependency injection\n\nFirst, 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.\n\n```c#\npublic class InjectServiceHandler(ILogger\u003cInjectServiceHandler\u003e logger)\n{\n    [ActionHandler]\n    public void Handle(Say say)\n    {\n        logger.LogInformation(\"InjectServiceHandled : \" + say.Text);\n    }\n}\n```\n```c#\nservices.AddSingleton\u003cInjectServiceHandler\u003e();\n```\n\n## Dispatcher\nYou can dispatch action with `IActionDispatcher`\n```c#\nvar dispatcher = services.GetRequiredService\u003cIActionDispatcher\u003e();\n\ndispatcher.Dispatch(new Say { Say = \"Hello World\" });\n```\nAsynchronous invocation is supported.\n```c#\nawait dispatcher.DispatchAsync(new Say { Say = \"Hello World\" });\n```\nLog console output\n\n```powershell\ninfo: ActionHandler[0]\n      StaticHandle : Hello World\ninfo: ActionHandler[0]\n      Handled : Hello World\ninfo: InjectServiceHandler[0]\n      InjectServiceHandled : Hello World\ninfo: ActionHandler[0]\n      AsyncHandled : Hello World\n```\n\n## Subscriber\nYou can subscribe action with `IActionSubscriber`, supprots `ActionDispatchStatus`:\n- ActionDispatchStatus.WaitingToDispatch\n- ActionDispatchStatus.Canceld\n- ActionDispatchStatus.Successed\n- ActionDispatchStatus.Faulted\n\n\n```c#\nvar subscriber = services.GetRequiredService\u003cIActionSubscriber\u003e();\n\nsubscriber.Subscribe\u003cSay\u003e(action =\u003e\n{\n    Console.WriteLine(\"Subscriber: Say action dispatched.\");\n});\n\nsubscriber.Subscribe\u003cSay\u003e(ActionDispatchStatus.WaitingToDispatch, action =\u003e\n{\n    Console.WriteLine(\"Subscriber: Say action dispatching.\");\n});\n\nsubscriber.Subscribe\u003cSay\u003e(ActionDispatchStatus.Faulted, (action, exception) =\u003e\n{\n    Console.WriteLine(\"Subscriber: Say action dispatch faulted.\");\n});\n\n//Subscribe all types action\nsubscriber.Subscribe\u003cobject\u003e(action =\u003e\n{\n    Console.WriteLine($\"Subscriber: {action.GetType()} action dispatched\");\n});\n\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsourcegeneration%2Factiondispatcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsourcegeneration%2Factiondispatcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsourcegeneration%2Factiondispatcher/lists"}