I have got a pipeline of tasks which basically is a variation of chain of responsibility pattern.
A task in my pipeline looks as below
internal interface IPTask<T>
{
bool CanExecute(T instance);
T Process(T instance);
}
..and my processor looks like
internal interface IProcessor<T>
{
T Execute(T instance);
}
and my concrete implementation looks like this:
public class Processor<T> : IProcessor<T>
{
private readonly ITasks<T> tasks;
public Processor(ITasks<T> tasks)
{
this.tasks= tasks;
}
public T Execute(T instance)
{
var taskstoExecute = tasks.GetTasks()
.Where(task => task.CanExecute(instance));
taskstoExecute.ToList().ForEach(task=>task.Process(instance));
return T;
}
}
..and my tasks look like this:
internal interface ITasks<T>
{
IEnumerable<IPTask<T>> GetTasks();
}
T could be different instances, but bound by a generic contract. One of the tasks are about mapping the incoming object into a completely different object and forwarding that instance from there onwards.
Now as you would see, I'm executing all the tasks in the pipeline, I would like to modify this to the following:
Execute
method for the next task should be from the previously executed task. CanExecute
fails for a task then the pipeline should stop processing the tasks.Can you please help me in getting this. Also would you expect the code to be structured differently for this purpose?
How about this:
public T Execute(T instance)
{
T result = instance;
foreach(var individual in tasks.GetTasks())
{
if(!individual.CanExecute()) break;
result = individual.Process(result);
}
return result;
}
As you have it currently, it is much more like a composite pattern than a chain of responsibility. This change makes it a little bit more CoR-ish. But it is more important to note whether it meets your needs than to use the correct design pattern jargon. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With