DEV Community

A. Shafie
A. Shafie

Posted on • Edited on

10 1

Implement Chain of Responsibility/Commands in C# Using ChainRunner

I have been working on an ASP.NET Core Web API application which is responsible for users' comments. The application receives new comments and based on multiple business criteria decides to whether reject or censor them. In nutshell, each new comment must go through the following steps:

  • Censor curse words
  • Modify incorrect words
  • Reject if it has improper tone

The steps are not that complex and must be executed sequentially. To implement these steps, I decided to go for chain of responsibility pattern. However, I could not find a simple and proper library to implement this pattern so I created a library called ChainRunner to make all this work.

ChainRunner Flow Diagram

The picture depicts how ChainRunner works

Implementation

Below you can seee how I used ChainRunner to implement the steps. For each step I created a responsibility handler:

public class CensorCurseWordsHandler : IResponsibilityHandler<Comment>
{
    public Task HandleAsync(Comment request, CancellationToken cancellationToken = default)
    {
        // process comment ...
    }
}

public class ModifyIncorrectWordsHandler : IResponsibilityHandler<Comment>
{
    public Task HandleAsync(Comment request, CancellationToken cancellationToken = default)
    {
        // process comment ...
    }
}

public class ImproperToneHandler : IResponsibilityHandler<Comment>
{
    public Task HandleAsync(Comment request, CancellationToken cancellationToken = default)
    {
        // process comment ...
    }
}

Enter fullscreen mode Exit fullscreen mode

Then, I configured the chain in Startup.cs (ASP.NET Core):

services.AddChain<Comment>()
        .WithHandler<CensorCurseWordsHandler>()
        .WithHandler<ModifyIncorrectWordsHandler>()
        .WithHandler<ImproperToneHandler>();
Enter fullscreen mode Exit fullscreen mode

Finally, I injected the chain into my class and ran the chain like so:


[ApiController]
[Route("[controller]")]
public class CommentController
{
    private readonly IChain<Comment> _chain;

    public CommentController(IChain<Comment> chain)
    {
        _chain = chain;
    }

    [HttpPost]
    public async Task<IActionResult> Post(Comment comment)
    {
        await _chain.RunAsync(comment);

        return Ok();
    }
}
Enter fullscreen mode Exit fullscreen mode

Links

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (1)

Collapse
 
alwaysmaap profile image
Mohammad ali Ali panah

Thanks that exacly what I was looking for <333

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

If this article connected with you, consider tapping ❤️ or leaving a brief comment to share your thoughts!

Okay