C# API Wrapper with Static Function Calls I'm creating a wrapper library for an API, and I hit a block on how to redesign it. The entire library is static, and I'd like to change it to make it more testable.

The library's goal is to make rest api requests and return C# objects. There is a networking class, which makes the requests. And there is a class for each endpoint which abstracts the parameters for the request and supplies the relative url.

Networking class: build url, create headers, and return results from request

public class APIClient{

private static string url = null;
private static string apiKey = null;

public static void Initialize(string key,string url)
    {
        APIClient.url = url;
        APIClient.apiKey = key;
    }

public static async Task&lt;T&gt; GetAsync&lt;T&gt;(string path, Dictionary&lt;string, string&gt; parameters)
    {
        var client = CreateHttpClientFromApiCredentials();

        //build url with parameters from the dictionary
        var builder = new UriBuilder("", path);
        builder.Port = -1;

        if (parameters != null)
        {
            var query = HttpUtility.ParseQueryString("");
            foreach (var key in parameters.Keys)
                query[key] = parameters[key];

            builder.Query = query.ToString();
        }

        var response = await client.GetAsync(builder.ToString());

        if (!response.IsSuccessStatusCode)
            throw new HttpException((int)response.StatusCode, response.ReasonPhrase);

        //evaluate API specific data
        return await EvaluateResponseContent&lt;T&gt;(response);
    }
}


Sample endpoint class: provide relative url and arguments to networking class

public class APIObject
{
    public static async Task&lt;List&lt;APIObject&gt;&gt; Get()
    {
        return await APIClient.GetAsync&lt;List&lt;APIObject&gt;&gt;("objectendpoint",null);
    }

}


This design allows for very simple use, with calls like APIObject.Get().

With that said, I have a redesign in mind that will maintain the simplicity of the static functions while also allowing for easy testing. The APIClient will be refactored to be an object, and each of the API object classes will be a nested class inside the APIClient.

A brief example (untested):

public class APIClient
{
    public ApiObjectSender ApiObjectEndpoint;

    public APIClient() {
        ApiObjectEndpoint = new ApiObjectSender(this);
    }

    public class ApiObjectSender
    {
        APIClient apiClient;

        public ApiObjectSender(APIClient cl)
        {
            apiClient = cl;
        }

        public List&lt;APIObject&gt; Get()
        {
            return apiClient.Get("apiobjectendpoint");
        }
    }
}


This allows for similar function calls, like clientVar.ApiObjectEndpoint.Get(). However, I can't help but feel like this approach is... janky.
public static void Initialize(string key,string url)
    {
        APIClient.url = url;
        APIClient.apiKey = key;
    }



This is a dead give away that this class shouldn't be a bunch of static methods. I have to call this initialize method before using it or it'll blow up with null reference exceptions. 

Worse, let's say I parallelize the main process and have multiple processes using this class. What happens when one of processes changes the uri? That's right, now all the processes are hitting that other uri. You'll get results, they'll just be the wrong one. 

Thankfully, it's a simple fix. Just turn your Initialize method into a constructor and remove all instances of the static keyword. 

public class APIClient
{
    private readonly string url;
    private readonly string apiKey;

    public APIClient(string key,string url)
    {
        this.url = url;
        this.apiKey = key;
    }