Prior to getting into DI I was quite a fan of using a so-called enum class (or strong enum in my head), where enumerations are turned into classes but set up to be used in a similar way to enums. This enables logic that really belongs to a specific enum to be encapsulated in the correct place and prevents lots of mess in the code base.
An example is the one found here http://lostechies.com/jimmybogard/2008/08/12/enumeration-classes/
Once you bring DI into the equation though it becomes problematic because of the reliance on static variables.
Is there any way of continuing to support this pattern and also use DI?
Edit: Here is an example of a type that is problematic if I want to inject some thing new into EmployeeType. I can't use the container due to the static variables.
public class EmployeeType : Enumeration
{
public static readonly EmployeeType Manager
= new ManagerType (0, "Manager");
public static readonly EmployeeType Servant
= new EmployeeType(1, "Servant");
public static readonly EmployeeType AssistantToTheRegionalManager
= new EmployeeType(2, "Assistant to the Regional Manager");
private EmployeeType() { }
private EmployeeType(int value, string displayName) : base(value, displayName) { }
}
public class ManagerType : EmployeeType
{
}
I think you can use Strategy pattern here. You can keep your enum type or use any type than can help you to identify the strategy (I will use string in my example). Then implement a strategy for each value.
interface IEmployeeHandler
{
string EmployeeType { get; }
void Handle(Employee employee);
}
class ManagerHandler : IEmployeeHandler
{
public ManagerHandler()
{
EmployeeType = "Manager";
}
public string EmployeeType { get; private set; }
public void Handle(Employee employee) { }
}
class ServantHandler : IEmployeeHandler
{
public ServantHandler()
{
EmployeeType = "Servant";
}
public string EmployeeType { get; private set; }
public void Handle(Employee employee) { }
}
Since DI containers can inject multiple implementations of an interface, you can write a strategy provider class like this:
class EmployeeStrategyProvider
{
private readonly IEmployeeHandler[] _employeeHandlers;
public EmployeeStrategyProvider(IEmployeeHandler[] employeeHandlers)
{
_employeeHandlers = employeeHandlers;
}
public IEmployeeHandler GetStrategy(string employeeType)
{
return _employeeHandlers.FirstOrDefault(item => item.EmployeeType == employeeType);
}
}
You can use this class to get the correct strategy depending on the employee type. This is how I implement Strategy pattern with DI containers. It can use some improvements though, I would be happy to hear some suggestions.