https://github.com/litenova/chainrunner
A simple and innovative library to help you implement a chain of responsibilities
https://github.com/litenova/chainrunner
chain-of-responsibility csharp
Last synced: 6 months ago
JSON representation
A simple and innovative library to help you implement a chain of responsibilities
- Host: GitHub
- URL: https://github.com/litenova/chainrunner
- Owner: litenova
- License: mit
- Created: 2021-05-16T22:00:55.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2023-04-21T17:01:40.000Z (over 2 years ago)
- Last Synced: 2025-04-10T14:12:22.882Z (6 months ago)
- Topics: chain-of-responsibility, csharp
- Language: C#
- Homepage:
- Size: 105 KB
- Stars: 13
- Watchers: 2
- Forks: 1
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![]()
ChainRunner
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* Written in .NET 7
* No Dependencies
* No Reflection
* Easy to Use## Installation
Depending on your usage, follow one of the guidelines below.
### ASP.NET Core
Install with NuGet:
```
Install-Package ChainRunner
Install-Package ChainRunner.Extensions.MicrosoftDependencyInjection
```or with .NET CLI:
```
dotnet add package ChainRunner
dotnet add package ChainRunner.Extensions.MicrosoftDependencyInjection
```and configure your desired as below in the `ConfigureServices` method of `Startup.cs`:
```c#
services.AddChain()
.WithHandler()
.WithHandler()
.WithHandler();
```## How to Use
Consider the following example and follow the sections in order:
You intend to execute a series of actions (i.e., PersistUserData, SubscribeUserToNewsletter, SendWelcomeEmail) when a new user signs up into system.
First, you create a class the contains all the necessary information to executes these actions.```c#
public class CompleteRegistrationRequest
{
public string UserId { get; set; }
}
```Then, for each action you create class that implements `IResponsibilityHandler` interface.
```c#
public class PersistUserDataHandler : IResponsibilityHandler
{
public Task HandleAsync(SendNotificationRequest request, CancellationToken cancellationToken = default)
{
// implementation goes here ...
}
}
public class SubscribeUserToNewsletterHandler : IResponsibilityHandler
{
public Task HandleAsync(SendNotificationRequest request, CancellationToken cancellationToken = default)
{
// implementation goes here ...
}
}
public class SendWelcomeEmailHandler : IResponsibilityHandler
{
public Task HandleAsync(SendNotificationRequest request, CancellationToken cancellationToken = default)
{
// implementation goes here ...
}
}
```### Setup Pre-Defined Chain with Dependency Injection Support
Setup your chain in the `ConfigureServices` method of `Startup.cs`
```c#
services.AddChain()
.WithHandler()
.WithHandler()
.WithHandler();
```Inject your chain to your desired class and run it
```c#
[ApiController]
[Route("[controller]")]
public class Controller
{
private readonly IChain _chain;public Controller(IChain chain)
{
_chain = chain;
}[HttpPost]
public async Task Register(CompleteRegistrationRequest request)
{
await _chain.RunAsync(request);return Ok();
}
}
```### Setup Chain on Demand with Dependency Injection Support
Inject `IChainBuilder` to your desired class and setup you chain.
```c#
[ApiController]
[Route("[controller]")]
public class Controller
{
private readonly IChainBuilder _chainBuilder;public Controller(IChainBuilder chainBuilder)
{
_chainBuilder = chainBuilder;
}
[HttpPost]
public async Task Register(CompleteRegistrationRequest request)
{
var chain = _chainBuilder.For()
.WithHandler()
.WithHandler()
.WithHandler()
.Build();await chain.RunAsync(request);
}
}
```
Before using `IChainBuilder`, make sure to call `AddChainRunner(assemblies)` method in `ConfigureServices()` of `Startup.cs` class to register `IChainBuilder` and handlers.```c#
public void ConfigureServices(IServiceCollection services)
{
services.AddChainRunner(typeof(PersistUserDataHandler).Assembly);
}
```### Setup Chain on Demand Without Dependency Injection Support
You can use the `ChainBuilder` 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.
```c#
[ApiController]
[Route("[controller]")]
public class Controller
{
[HttpPost]
public async Task Register(CompleteRegistrationRequest request)
{
var chain = ChainBuilder.For()
.WithHandler() // pass the handler with empty constructor
.WithHandler() // pass the handler with empty constructor
.WithHandler(new SendWelcomeEmailHandler()) // pass the handler instance
.Build();
await chain.RunAsync(request);
}
}
```