How to load Func<T> from configuration file - Factory pattern - Open Closed principal

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.

Answers


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.


Need Your Help

Is there a transformation matrix that can scale the x and/or y axis logarithmically?

wpf math matrix transform

I'm using .net WPF geometry classes to graph waveforms. I've been using the matrix transformations to convert from the screen coordinate space to my coordinate space for the waveform. Everything w...

How to circumvent the depth limitation of Excel's IF function?

excel excel-formula

For an Excel formula I need the first cell out of a list of cells which contains a numeric value: