asharpharp
asharpharp

Reputation: 169

How to create a Factory that returns an object with specific parameters?

I have this generic function

private static T PostNew<T>() where T : IHttpModel, new()
    {
        var t = HttpModelsFactory.Create<T>();
        var requestT = new RestRequest("/households", Method.POST);
        requestT.AddParameter("application/json", t.ToJson(), ParameterType.RequestBody);
        return t;
    }

It needs to create and send an object of type T. This object, however, needs to have specific properties depending on what the type is.

class HttpModelsFactory
{
    public static T Create<T>() where T : IHttpModel, new()
    {
        Type typeofT = typeof(T);
        
        if (typeofT.Equals(typeof(Household)))
        {
            return CreateHousehold() as T;
        }
    }

    public static Household CreateHousehold()
    {
        return new Household
        {
            Name = Randoms.RandomString()
        };
    }
}

This will have many more classes than just Household. However, it currently gives me this error: "The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint." How can I refactor the code to make it work or is there a better solution?

Upvotes: 2

Views: 325

Answers (1)

Nkosi
Nkosi

Reputation: 247018

Add the class constraint, and you can also have a delegate to apply any actions on the created object

class HttpModelsFactory {
    public static T Create<T>(Action<T> configure = null) 
        where T : IHttpModel, class, new() {

        T result = new T();
        
        if(configure != null) configure(result);

        return result;
    }
}

That however now means that it needs to bubble up to where it is being used.

private static T PostNew<T>(Action<T> configure = null) 
    where T : IHttpModel, class, new() {

    var model = HttpModelsFactory.Create<T>(configure);
    var request = new RestRequest("/households", Method.POST);
    request.AddParameter("application/json", model.ToJson(), ParameterType.RequestBody);

    //...

    return model;
}

resulting in an invocation of PostNew that might look something like

//...

var result = PostNew<Household>(h => {
    h.Name = Randoms.RandomString();
});

//...

Upvotes: 3

Related Questions