jeudi 28 mars 2019

c# - Can I refactor functions that have similar inputs but call different services into one generic function?

I am looking for a way to combine x amount of very similar CRUD functions into one without having to use x amount of if else statements to check the type of a generic.

I have Web API controllers that I want to make calls from like this:

Service.Get<FooModel>(number, type, part, version); 

This is to prevent having to have an extremely similar function for 40+ API endpoints. The issue is when I receive this in my service, I have to check the type of the generic given and compare with those 40+ object types in the one function. All of the models currently inherit from a base inherited model.

Current generic function

(Create, Update, Delete functions are similar):

public T Get<T>(string documentNr, string type, string part, string version) where T : InheritedModel, new()
{
    try
    {
        T model = new T();

        if (typeof(T) == typeof(InheritedModel))
        {
           using (var repo = new InheritedModelConsumer(ref _helper))
           {
                model = (T)repo.Get(documentNr, type, part, version);
           }
        }
        else if (typeof(T) == typeof(FooModel))
        {
            using (var repo = new FooModelConsumer(ref _helper))
            {
                model = (T)(object)repo.Get(documentNr, type, part, version);
            }
        }
        else if (typeof(T) == typeof(ComponentModel))
        {
            using (var repo = new ComponentModelConsumer(ref _helper))
            {
                model = (T)(object)repo.Get(documentNr, type, part, version);
            }
        }
        else if (typeof(T) == typeof(BarModel))
        {
            using (var repo = new BarModelConsumer(ref _helper))
            {
               model = (T)(object)repo.Get(documentNr, type, part, version);
            }
        }
        ... and so on
        ... and so on
        ...
        else
            throw new Exception("Type T structure not defined");

        return model;
    }
    catch (Exception)
    {

        throw;
    }
    finally
    {
        _helper.Dispose();
    }
}

This does work, but if it is possible I am looking for something where I can say at run time, "oh I have this object of Type T, and well since I know the functions all have the same inputs I'm going to instantiate this consumer of Type TConsumer, call consumer.Get(inputs), and then return an object of T to whatever API controller called me."

Aucun commentaire:

Enregistrer un commentaire