Mhyk Gyver
Mhyk Gyver

Reputation: 228

convert to generic method

I have this recurring method that I need to convert to a generic method. I'm using .net core 2.0, and I'm creating a new set of APIs calling a remote API. I will be using the resulting data in my angular front-end as well as enabling authentication and authorization that the remote API doesn't provide. The recurring code is similar to the ff:

[HttpGet("getAddressBook")]
public async Task<IActionResult> GetAddressBook()
{
    string BaseURL = Configuration.GetSection("AppSettings:BaseURL").Value;
    AddressBookRootObject AddressBookInfo = new AddressBookRootObject();

    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(BaseURL);

        client.DefaultRequestHeaders.Clear();

        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpResponseMessage Res = await client.GetAsync("/v1/addressBook_get");

        if (Res.IsSuccessStatusCode) 
        {
            var ParametersResponse = Res.Content.ReadAsStringAsync().Result;

            AddressBookInfo = JsonConvert.DeserializeObject<AddressBookRootObject>(ParametersResponse);
        }
        else 
        {
            return BadRequest("Error retrieving data from server");
        }

        return Ok(AddressBookInfo.data);
    }       
}

I have no issues with this code, it runs perfectly but I need to convert it to a generic method as I have tons of remote API calls that uses the above code. I have checked this link:

Converting Method to Generic Method?

but I can't figure out how to convert the

AddressBookRootObject AddressBookInfo = new AddressBookRootObject();

to a generic one. Any help is highly appreciated. TIA.

Upvotes: 2

Views: 347

Answers (1)

Nkosi
Nkosi

Reputation: 247323

Create simple web service abstraction of the desired functionality

public interface IHttpClient {
    Task<T> GetAsync<T>(string uri);
}

With an implementation that encapsulates the common functionality in the action.

public class WebService: IHttpClient {
    private readonly HttpClient client;

    public WebService(IConfiguration configuration) {
        string BaseURL = configuration.GetSection("AppSettings:BaseURL").Value;
        client = new HttpClient();
        client.BaseAddress = new Uri(BaseURL);
        client.DefaultRequestHeaders.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<T> GetAsync<T>(string url) {
        var result = default(T);
        var response = await client.GetAsync(url);
        if (response.IsSuccessStatusCode) {
            var json = await response.Content.ReadAsStringAsync();
            result = JsonConvert.DeserializeObject<T>(json);
        }
        return result         
    }
}

The controller would have the service injected and the action refactored

private readonly IHttpClient client;
public AddressBookController(IHttpClient client) {
    this.client = client;
}

[HttpGet("getAddressBook")]
public async Task<IActionResult> GetAddressBook() { 
    var AddressBookInfo = await client.GetAsync<AddressBookRootObject>("/v1/addressBook_get");
    if (AddressBookInfo != null) {
        return Ok(AddressBookInfo.data);
    } else  {
        return BadRequest("Error retrieving data from atCom server");
    }
}

The abstraction can be updated to include more common functionality as needed.

Finally make sure abstraction and implementation are registered with server collection.

services.AddSingleton<IHttpClient, WebService>();

Upvotes: 1

Related Questions