mardi 27 août 2019

Order of execution in Command pattern

I have a fairly basic implementation of a command pattern, along these lines:

    interface IProcessor
    {
        bool CanProcess(string input);
        void Process(string input);
    }

    class ProcessorA : IProcessor
    {
        public bool CanProcess(string input)
        {
            return true;
        }

        public void Process(string input)
        {
            // do things
        }
    }
// and other implementations, ProcessorB, ..C, etc.

Processors will get injected with DI and I'll have a loop that finds a valid processor and executes it, something along these lines:

foreach (var processor in processors)
{
    if (processor.CanProcess("abc"))
    {
        processor.Process("abc");
    }
}

So far so good, except that one of these processors is a fall-through processor which needs to be executed when all other processors have declared that they can't process - basically I have to ensure it is executed last because it can process anything. The problem is that this is an unordered list, so I need to figure out how to make fall-through processor execute last.

I see a few ways:

  • Make a pass-through processor a special case, make it implement a specific interface and explicitly call it when all other processors were exhausted. This adds a check after the loop and an extra interface (IPassThruProcessor) for DI.
  • Add a marker property on IProcessor interface and sort processors prior to the loop:

interface IProcessor { bool CanProcess(string input); void Process(string input); bool IsPassThru { get; set; } // new prop }

var processors = processors.OrderBy(x => x.IsPassThru).ToArray(); 
// IsPassThru = true goes to the back of the queue

// loop over processors

I don't really like either of these ways, first - because it introduces special cases and special interfaces, second - because the processor knows something about itself that is an external piece of information.

Any suggestions on how to design this?

Aucun commentaire:

Enregistrer un commentaire