0

I am writing a list of filters as a chain and each filter has the next link in its constructor so if a certain chain link can't handle the request it passes it along until it can.

public class SomeFilter : ISomeFilter<ForSomeClass> 
{
        private readonly ISomeFilter<ForSomeClass> _next;

        public SomeFilter(ISomeFilter<ForSomeClass> next)
        {
            _next = next;
        }

        public bool IsRelevant()
        {
           // try to handle it
           return _next?.IsRelevant(args) ?? false;
        }
}  

This is how I registered:

    container.Register(Classes.FromAssemblyContaining<ForSomeClass>()
     .BasedOn(typeof(ISomeFilter<>))
     .WithServiceAllInterfaces()
     .LifestyleTransient());

I have encountered two problems:

  1. When I get to the the last part of the chain that I registered, it loops back to the first one but I want it to stop. I currently thought of these solutions but none of them are good:
  • The last chain of the link should not have a next - but this creates a problem, if somebody wants to add another last link they will need to understand that this is the last part of the link and correct the other class, this breaks the single responsibility.
  • Implement a null object implementation and inject that always at the end. - Its a whole implementation just to stop a loop.
  • Inject a null as the implementation - The IoC doesn't support this.
  1. I can't order the implementations so they get injected in the order I want. The only way I found I can do it is to literally register them one by one but I have 17 filters and I have register each of them and remember the order of them all and see where the last of them by generic type are. Its very tedious.

Anyone got any suggestions to these 2 problems? How to register the implementations to solve these 2 problems?

2
  • 1
    From your description, it seems obvious that you're going to have to mark the last node in some way. Which way of marking the last node is the most desirable or least painful? Personally, a null object isn't the worst idea I've ever heard. Pass-through filters are a thing. Commented Mar 8, 2022 at 0:09
  • Yea the pass through filter is basically a null object, I just wish I could register null as the implementation Commented Mar 8, 2022 at 0:13

1 Answer 1

0

The only possible solution I found was to add a fall through filter as suggested in the comments:

public class DefaultFilter : ISomeFilter<ForSomeClass> 
{
        public bool IsRelevant()
        {
           return false;
        }
}  
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.