Below is my factory class:
public class BulkFactory<T>
{
private BulkFactory() { }
static readonly Dictionary<string, Func<T>> _dict
= new Dictionary<string, Func<T>>();
public static T Create(string id)
{
Func<T> constructor = null;
if (_dict.TryGetValue(id, out constructor))
return constructor();
throw new ArgumentException("No type registered for this id");
}
public static void Register(string id, Func<T> ctor)
{
_dict.Add(id, ctor);
}
}
And this is how I am registering various bulk job to this factory:
BulkFactory<IBulk>.Register("LCOUPD", () => new BAT_LCOUPD<BulkLCOUpdateRecord, BAT_LCOUPD_LOG>(bulkJobCode));
BulkFactory<IBulk>.Register("STBILL", () => new BAT_STBILL<BulkStartStopBillUpdateRecord, BAT_STBILL_LOG>(bulkJobCode));
BulkFactory<IBulk>.Register("PLANCH", () => new BAT_PLANCH<BulkPlanChangeUpdateRecord, BAT_PLANCH_LOG>(bulkJobCode));
BulkFactory<IBulk>.Register("CSCORE", () => new BAT_CSCORE<BulkCSCOREUpdateRecord, BAT_CSCORE_LOG>(bulkJobCode));
BulkFactory<IBulk>.Register("CUSTAQ", () => new BAT_CUSTAQ<CustomerAcquisitionTemplate, BAT_CUSTAQ_LOG>(bulkJobCode));
In order to follow Open Closed principal I want to store all these register entries into configuration file and wanted to load it back from configuration. So that whenever I add a new bulk job I need not to modify above lines of code.
Please suggest how can I achieve this.
Assuming you have a FactoryMethod
array:
public sealed class FactoryMethod {
public string Name { get; set; }
public string Type { get; set; }
}
Which you somehow read from your configuration file where Name
is class name you want to register (LCOUPD
, STBILL
and so on) and Type
is in the format required by Type.GetType() for generic types:
TClass`2[TGenericType1, TGenericType2].
For example (assuming a fictional namespace Ns
):
Ns.BAT_CUSTAQ`2[Ns.CustomerAcquisitionTemplate, Ns.BAT_CUSTAQ_LOG]
Then you may write this code:
foreach (var factoryMethod in factoryMethods) {
BulkFactory<IBulk>.Register(factoryMethod.Name,
(IBulk)Activator.CreateInstance(Type.GetType(factoryMethod.Type), bulkJobCode));
}
Note that I don't know exact type of your classes and prototype of your functions then you may need a cast here or there.