I have a method with some generic type parameters; T,U,V. I am using it with another helper method GetAPIResponseAsync()
to download all pages of records from a downstream API endpoint that has paging enabled, deserializing the JSON responses, and mapping them into a aggregated list of new objects of a type that better suits the front end website this API is serving.
'T' represents the destination type of the objects once they have been mapped.
'U' represents the class that the JSON responses from the downstream API are deserialised into.
'V' represents the type of the objects in the 'Data' property in the 'U' class. U classes will always have a Data property of type List<V>
because they inherit from FabricListResponse<V>
, which defines a property of that type in the class definition.
I want to remove the generic type parameter 'V' from GetAllPagesAsync
because the generic type for FabricContactsResponse
is specified in the class definition so it feels like I'm repeating myself. But I'm not sure how to do it without creating syntax errors...
public async Task<ContactsResponse> GetAccountContactsAsync(string accountId, ILogger log)
{
var contacts = await GetAllPagesAsync<ContactDTO,FabricContactsResponse,FabricContactDTO>($"/v1/account/{accountId}/contacts", log);
var response = new ContactsResponse
{
Contacts = mapper.Map<List<ContactDTO>>(contacts)
};
return response;
}
private async Task<List<T>> GetAllPagesAsync<T,U,V>(string endpoint, ILogger log)
where T : class
where U : FabricListResponse<V>
where V : class
{
var contacts = new List<T>();
U fabricApiResponse;
var page = 1;
do
{
fabricApiResponse = await apiService.GetAPIResponseAsync<U>(endpoint, page, log);
contacts.AddRange(mapper.Map<List<T>>(fabricApiResponse.Data));
page++;
} while (fabricApiResponse.TotalPages > fabricApiResponse.CurrentPage);
return contacts;
}
public class FabricContactsResponse : FabricListResponse<FabricContactDTO>;
public class FabricContactDTO : FabricContactResponse;
It seems that FabricContactsResponse
is not required.
I'm not sure that's what you want:
public async Task<ContactsResponse> GetAccountContactsAsync(string accountId, ILogger log)
{
var contacts = await GetAllPagesAsync<ContactDTO, FabricContactDTO>($"/v1/account/{accountId}/contacts", log);
var response = new ContactsResponse
{
Contacts = mapper.Map<List<ContactDTO>>(contacts)
};
return response;
}
private async Task<List<T>> GetAllPagesAsync<T, V>(string endpoint, ILogger log)
where T : class
where V : class
{
var contacts = new List<T>();
FabricListResponse<V> fabricApiResponse;
var page = 1;
do
{
fabricApiResponse = await apiService.GetAPIResponseAsync<FabricListResponse<V>>(endpoint, page, log);
contacts.AddRange(mapper.Map<List<T>>(fabricApiResponse.Data));
page++;
} while (fabricApiResponse.TotalPages > fabricApiResponse.CurrentPage);
return contacts;
}