An alternative option using Reflection and following the Strategy Pattern.
1) Create a base class for the constructors' arguments
public abstract class ConstructorArgs
{
}
2) Create a sequence of different concrete arguments classes:
public class StringArg : ConstructorArgs
{
public string _gradeTypeStringFromXmlFile { get; set; }
public StringArg (string gradeTypeStringFromXmlFile)
{
this._gradeTypeStringFromXmlFile = gradeTypeStringFromXmlFile ;
}
}
public class EnumArg : ConstructorArgs
{
public Enum.GradeType _gradeType { get; set; }
public EnumArg (Enum.GradeType gradeType)
{
this._gradeType = gradeType ;
}
}
3) Now in your GradeType class create the methods required for the Reflection. The ParseArguments scans the args for properties and for each one that it finds, it copies its value to the respective property of the GradeType using the SetProperty. Since it uses the property name for the matching, it is important to keep the same property name across both the GradeType and the concrete ConstructorArgs:
private void SetProperty(String propertyName, object value)
{
var property = this.GetType().GetProperty(propertyName);
if (property != null)
property.SetValue(this, value);
}
private void ParseArguments(ConstructorArgs args)
{
var properties = args.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
this.SetProperty(propertyInfo.Name,
args.GetType().GetProperty(propertyInfo.Name).GetValue(args));
}
}
4) In your GradeType class create the respective properties (mind that you must use exactly the same names and types that you used in the concrete ConstructorArgs but you can use any access modifiers you like)
public string _gradeTypeStringFromXmlFile { get; set; }
public Enum.GradeType _gradeType { get; set; }
5) Create a constructor for your GradeType class with a parameter of type ConstructorArgs:
public GradeType(ConstructorArgs args)
{
this.ParseArguments(args);
}
6) Now you can register the GradeType in Unity using a single constructor but you can pass in different types as arguments when resolving it:
_unityContainer.RegisterType<IGradeType, GradeType>(
new InjectionConstructor( typeof(ConstructorArgs) ));
var args1 = new StringArg(gradeTypeStringFromXmlFile); // string
IGradeType gradeType1 = _unityContainer.Resolve<IGradeType>(
new ResolverOverride[]{new ParameterOverride("args", args1)});
var args2 = new EnumArg(gradeType); // enum
IGradeType gradeType2 = _unityContainer.Resolve<IGradeType>(
new ResolverOverride[]{new ParameterOverride("args", args2)});
If you are planning to repeatedly resolve your type in an iteration that approach might not be ideal, since Reflection comes with a performance penalty.
Enum.Parse
on the gradeType string before creating the class? – jgauffin