Shivang MIttal
Shivang MIttal

Reputation: 1001

Factory pattern, Avoid same switch case for different interface

I have a Model which Implements 3 different interfaces

public class CustomerRateSettingModel :  IBaseFactory, IHandleSearch, IHandleSearchAggregate

I am very new with implementing design patterns and trying to implement Factory pattern to create instances. But I am unable to find a proper way to avoid the identical Switch statements while writing Factory

  public static IHandleSearch GetClassInstanceForSearch(string className)
    {
        switch (className.ToLower())
        {
            case "customerratesettingmodel":
                return new CustomerRateSettingModel();

            default: return null;
        }
    }

    private static IBaseFactory ManufactureModel(string className)
    {
        switch (className.ToLower())
        {
            case "customerratesettingmodel":
                return new CustomerRateSettingModel();

            default: return null;
        }
    }

Is there is any right way to handle scenarios like that?

For Reference : the code calling the factory

  IHandleSearch instance = ModelFactory.GetClassInstanceForSearch(modelName);


 var modelResult = instance.GetSearch(indexName, searchHistory.SearchParameters);

Upvotes: 2

Views: 997

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726499

Make a Dictionary<string,Func<object>> to map names to object makers. Use as operator to test object for compliance with the desired interface:

static readonly IDictionary<string,Func<object>> Makers = new Dictionary<string,Func<object>> {
    ["customerratesettingmodel"] = () => new CustomerRateSettingModel()
};
public static IHandleSearch GetClassInstanceForSearch(string className) {
    return Construct<IHandleSearch>(className);
}
public static IBaseFactory GetClassInstanceForSearch(string className) {
    return Construct<IBaseFactory>(className);
}
private static T Construct<T>(string className) where T : class {
    if (!Makers.TryGetValue(className.ToLower(), out var makeObject) {
        return null;
    }
    return makeObject() as T;
}

Upvotes: 4

Related Questions