In the previous post I worked through how to implement the strategy pattern and register multiple implementations of the same interface in the ASP.Net Core DI framework. In this post I want to look at another way of implementing the same pattern without having an enum applicable property but an IsApplicable method.

Strategy update to use IsApplicable

To implement this idea I have updated the original post code and tweaked the IMathOperator to have an IsApplicable method instead of a public property which returns an enum.

public interface IMathOperator
{
    bool IsApplicable(Operator op);

    int Calculate(int a, int b);
}

I am still using an enum to determine whether it’s applicable or not but this could now be a struct or specific class instance which is passed through at the calling point.

For example AddOperator now looks like this:

public class AddOperator : IMathOperator
{
    public bool IsApplicable(Operator op)
    {
        return op == Operator.Add;
    }

    public int Calculate(int a, int b) => a + b;
}

Once now implemented in each of the operators I then had to change the MathStrategy implementation to be able to handle the update.

public class MathStrategy : IMathStrategy
{
    private readonly IEnumerable<IMathOperator> _operators;

    public MathStrategy(IEnumerable<IMathOperator> operators)
    {
        _operators = operators;
    }

    public int Calculate(int a, int b, Operator op)
    {
        foreach (var @operator in _operators)
        {
            if (@operator.IsApplicable(op))
            {
                return @operator.Calculate(a, b);
            }
        }

        throw new ArgumentNullException(nameof(op));
    }
}

Extensions

In the above I am still only applying a single action per “operator” in other implementations you may have to remove the return and exception throwing as multiple operators maybe applicable!

Conclusion

In this post we have looked at how to update the Strategy pattern implementation from the original post to not rely on an enum property but have an IsApplicable method which allows for more complicated logic as to when an action should be applied. The updated code still uses an enum but is not required to.

A full working example can be found on Github.

Any questions/comments then please contact me on Twitter @WestDiscGolf