{"id":24042429,"url":"https://github.com/litenova/chainrunner","last_synced_at":"2026-03-03T02:39:44.726Z","repository":{"id":48796093,"uuid":"367993537","full_name":"litenova/ChainRunner","owner":"litenova","description":"A simple and innovative library to help you implement a chain of responsibilities","archived":false,"fork":false,"pushed_at":"2023-04-21T17:01:40.000Z","size":108,"stargazers_count":13,"open_issues_count":3,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-10T14:12:22.882Z","etag":null,"topics":["chain-of-responsibility","csharp"],"latest_commit_sha":null,"homepage":"","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/litenova.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":"2021-05-16T22:00:55.000Z","updated_at":"2024-10-09T03:37:53.000Z","dependencies_parsed_at":"2025-01-08T22:55:31.548Z","dependency_job_id":"57645e99-0f35-49f0-ab86-972e87668883","html_url":"https://github.com/litenova/ChainRunner","commit_stats":{"total_commits":31,"total_committers":4,"mean_commits":7.75,"dds":0.4193548387096774,"last_synced_commit":"86cdf10250c36271cae38b5f4ecea6999061b68f"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litenova%2FChainRunner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litenova%2FChainRunner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litenova%2FChainRunner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litenova%2FChainRunner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/litenova","download_url":"https://codeload.github.com/litenova/ChainRunner/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249795885,"owners_count":21326780,"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":["chain-of-responsibility","csharp"],"created_at":"2025-01-08T22:55:23.140Z","updated_at":"2026-03-03T02:39:44.686Z","avatar_url":"https://github.com/litenova.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://github.com/litenova/ChainRunner\"\u003e\n    \u003cimg src=\"assets/logo/chain_128x128.png\"\u003e\n  \u003c/a\u003e\n  \u003cbr\u003e\n  ChainRunner\n  \u003cbr\u003e\n\u003c/h1\u003e\n\n\u003ch4 align=\"center\"\u003e\n    A simple and innovative library to implement chain of responsibilities. To learn more about chain of responsibilities pattern, read the following article https://refactoring.guru/design-patterns/chain-of-responsibility\n\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n\n  \u003ca href=\"https://github.com/litenova/ChainRunner/actions/workflows/release.yml\"\u003e\n    \u003cimg src=\"https://github.com/litenova/ChainRunner/actions/workflows/release.yml/badge.svg\" alt=\"CI/CD Badge\"\u003e\n  \u003c/a\u003e\n\n   \u003ca href='https://coveralls.io/github/litenova/ChainRunner?branch=main'\u003e\n    \u003cimg src='https://coveralls.io/repos/github/litenova/ChainRunner/badge.svg?branch=main' alt='Coverage Status' /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.nuget.org/packages/ChainRunner\"\u003e\n    \u003cimg src=\"https://img.shields.io/nuget/vpre/ChainRunner.svg\" alt=\"ChainRunner Nuget Version\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\n* Written in .NET 7\n* No Dependencies\n* No Reflection\n* Easy to Use\n\n## Installation\n\nDepending on your usage, follow one of the guidelines below.\n\n### ASP.NET Core\n\nInstall with NuGet:\n\n```\nInstall-Package ChainRunner\nInstall-Package ChainRunner.Extensions.MicrosoftDependencyInjection\n```\n\nor with .NET CLI:\n\n```\ndotnet add package ChainRunner\ndotnet add package ChainRunner.Extensions.MicrosoftDependencyInjection\n```\n\nand configure your desired as below in the `ConfigureServices` method of `Startup.cs`:\n\n```c#\n    services.AddChain\u003cChainRequest\u003e()\n            .WithHandler\u003cResponsibilityHandler1\u003e()\n            .WithHandler\u003cResponsibilityHandler2\u003e()\n            .WithHandler\u003cResponsibilityHandler3\u003e();\n```\n\n## How to Use\n\nConsider the following example and follow the sections in order:\n\nYou intend to execute a series of actions (i.e., PersistUserData, SubscribeUserToNewsletter, SendWelcomeEmail) when a new user signs up into system.\nFirst, you create a class the contains all the necessary information to executes these actions. \n\n```c#\n    public class CompleteRegistrationRequest\n    {\n        public string UserId { get; set; }\n    }\n```\n\nThen, for each action you create class that implements `IResponsibilityHandler` interface.\n\n```c#\n    public class PersistUserDataHandler : IResponsibilityHandler\u003cCompleteRegistrationRequest\u003e\n    {\n        public Task HandleAsync(SendNotificationRequest request, CancellationToken cancellationToken = default)\n        {\n            // implementation goes here ...\n        }\n    }\n    \n    public class SubscribeUserToNewsletterHandler : IResponsibilityHandler\u003cCompleteRegistrationRequest\u003e\n    {\n        public Task HandleAsync(SendNotificationRequest request, CancellationToken cancellationToken = default)\n        {\n            // implementation goes here ...\n        }\n    }\n    \n    public class SendWelcomeEmailHandler : IResponsibilityHandler\u003cCompleteRegistrationRequest\u003e\n    {\n        public Task HandleAsync(SendNotificationRequest request, CancellationToken cancellationToken = default)\n        {\n            // implementation goes here ...\n        }\n    }\n```\n\n### Setup Pre-Defined Chain with Dependency Injection Support\n\nSetup your chain in the `ConfigureServices` method of `Startup.cs`\n\n```c#\n    services.AddChain\u003cCompleteRegistrationRequest\u003e()\n            .WithHandler\u003cPersistUserDataHandler\u003e()\n            .WithHandler\u003cSubscribeUserToNewsletterHandler\u003e()\n            .WithHandler\u003cSendWelcomeEmailHandler\u003e();\n```\n\nInject your chain to your desired class and run it\n\n```c#\n    [ApiController]\n    [Route(\"[controller]\")]\n    public class Controller\n    {\n        private readonly IChain\u003cCompleteRegistrationRequest\u003e _chain;\n\n        public Controller(IChain\u003cCompleteRegistrationRequest\u003e chain)\n        {\n            _chain = chain;\n        }\n\n        [HttpPost]\n        public async Task\u003cIActionResult\u003e Register(CompleteRegistrationRequest request)\n        {\n            await _chain.RunAsync(request);\n\n            return Ok();\n        }\n    }\n```\n\n### Setup Chain on Demand with Dependency Injection Support\n\nInject `IChainBuilder` to your desired class and setup you chain.\n\n```c#\n    [ApiController]\n    [Route(\"[controller]\")]\n    public class Controller\n    {\n        private readonly IChainBuilder _chainBuilder;\n\n        public Controller(IChainBuilder chainBuilder)\n        {\n            _chainBuilder = chainBuilder;\n        }\n        \n        [HttpPost]\n        public async Task\u003cIActionResult\u003e Register(CompleteRegistrationRequest request)\n        {\n            var chain = _chainBuilder.For\u003cCompleteRegistrationRequest\u003e()\n                                     .WithHandler\u003cPersistUserDataHandler\u003e()\n                                     .WithHandler\u003cSubscribeUserToNewsletterHandler\u003e()\n                                     .WithHandler\u003cSendWelcomeEmailHandler\u003e()\n                                     .Build();\n\n            await chain.RunAsync(request);                 \n        }\n    }    \n```\nBefore using `IChainBuilder`, make sure to call `AddChainRunner(assemblies)` method in `ConfigureServices()` of `Startup.cs` class to register `IChainBuilder` and handlers.\n\n```c#\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddChainRunner(typeof(PersistUserDataHandler).Assembly);\n    }\n```\n\n### Setup Chain on Demand Without Dependency Injection Support\n\nYou can use the `ChainBuilder\u003cT\u003e` class to build chains without the need of DI. The `WithHandler()` method either accepts a handler with empty constructor or a pre-initialized instance of a handler.\n\n```c#\n    [ApiController]\n    [Route(\"[controller]\")]\n    public class Controller\n    {\n        [HttpPost]\n        public async Task\u003cIActionResult\u003e Register(CompleteRegistrationRequest request)\n        {\n        \n            var chain = ChainBuilder.For\u003cCompleteRegistrationRequest\u003e()\n                                    .WithHandler\u003cPersistUserDataHandler\u003e() // pass the handler with empty constructor\n                                    .WithHandler\u003cSubscribeUserToNewsletterHandler\u003e() // pass the handler with empty constructor\n                                    .WithHandler(new SendWelcomeEmailHandler()) // pass the handler instance \n                                    .Build();              \n            \n            await chain.RunAsync(request);                    \n        }\n    }\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitenova%2Fchainrunner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flitenova%2Fchainrunner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitenova%2Fchainrunner/lists"}