Map rental cost strategy It is the case where data contains some field indicating what type of strategy should be picked.

I mean, I often ignore solving the problem like shown below and duplicate the problems that strategy pattern is out to solve in the first place. Is there a pattern for it or is it not viable at all in this case?

Recent example on how I have solved it:

public class MapRentalCostStrategy : IMapper&lt;EquipmentType, IRentalCostStrategy&gt;
{
    private readonly Dictionary&lt;EquipmentType, IRentalCostStrategy&gt; _knownRentalCostStrategy;

    public MapRentalCostStrategy(IMutablePriceConfiguration mutablePriceConfiguration)
    {
        _knownRentalCostStrategy = new Dictionary&lt;EquipmentType, IRentalCostStrategy&gt;
        {
            { EquipmentType.Heavy, new HeavyRentalCostStrategy(mutablePriceConfiguration)},
            { EquipmentType.Specialized, new SpecializedRentalCostStrategy(mutablePriceConfiguration)},
            { EquipmentType.Regular, new RegularRentalCostStrategy(mutablePriceConfiguration)}
        };
    }

    public Func&lt;EquipmentType, IRentalCostStrategy&gt; Create =&gt; equipment =&gt;
    {
        if (!_knownRentalCostStrategy.ContainsKey(equipment))
            throw new ArgumentException();

        return _knownRentalCostStrategy[equipment];
    };
}


where EquipmentType is an enum.

Maybe I should inject a service that returns this dictionary? In any case, it seems I am delegating the responsibility (in this case its "object creation", it should not be mappers responsibility to deal with the instantiation of the dictionary).

Maybe I am on the wrong track? Is there a better way?
I think a singleton/enum like pattern would be beneficial. The curious part is the IMutablePriceConfiguration object seems to vary based on the situation.

Remove the IMutablePriceConfiguration as a dependency for the cost strategy objects.

Next:

public sealed class EquipmentType
{
    public static readonly Heavy = new EquipmentType(1, "Heavy", new HeavyRentalCostStrategy());
    public static readonly Specialized = new EquipmentType(2, "Specialized", new SpecializedRentalCostStrategy());
    public static readonly Regular = new EquipmentType(3, "Regular", new RegularRentalCostStrategy());

    public static readonly IEnumerable&lt;EquipmentType&gt; All = new EquipmentType[]
    {
        Heavy,
        Specialized,
        Regular
    };

    public static EquipmentType Find(int id)
    {
        return All.SingleOrDefault(e =&gt; e.Id == id);
    }

    public static EquipmentType Find(string name)
    {
        return All.SingleOrDefault(e =&gt; e.Name == name);
    }

    private IRentalCostStrategy CostStrategy { get; set; }
    public string Name { get; private set; }
    public int Id { get; private set; }

    private EquipmentType(int id, string name, IRentalCostStrategy costStrategy)
    {
        Id = id;
        Name = name;
        CostStrategy = costStrategy;
    }

    public double CalculateRentalCost(IMutablePriceConfiguration mutablePriceConfiguration)
    {
        return CostStrategy.CalculateRentalCost(mutablePriceConfiguration);
    }
}



The IMutablePriceConfiguration becomes an argument to the CalculateRenderCost method on the EquipmentType class
The EquipmentType class has a private constructor so you are guaranteed to only have those three instances available. No one can incorrectly (or maliciously) create equipment types and their cost strategies.
You can access each equipment type in an enum-like syntax:

EquipmentType.Regular

You can find by id or name:

EquipmentType.Find(1);
EquipmentType.Find("Specialized");

You can blindly loop over all available equipment types:

foreach (var equipmentType in EquipmentType.All)
{
    // ...
}

As long as you have an IMutablePriceConfiguration object, you can blindly call the CalculateRentalCost method and get a result back. No need for ifs or switchs peppered all over your code.