Я пытаюсь создать сервис MVC, который вызывает 2 разных API - Amazon и Apple.Код выглядит следующим образом:
public abstract class ApiHttpCaller<T>
{
protected static HttpClient _client;
protected ApiHttpCaller()
{
_client = new HttpClient();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public abstract Task<T> RetrieveApiResultAsync(string searchValue);
}
Этот ApiHttpCaller реализован с помощью моих двух спецификаций AmazonApiCaller и AppleApiCaller, давайте рассмотрим только одну из них:
public class AmazonApiCaller : ApiHttpCaller<AmazonResponseModel>
{
protected static IOptions<ApiUrls> _apiUrls;
public AmazonApiCaller(IOptions<ApiUrls> apiUrls)
{
_apiUrls = apiUrls;
}
public override async Task<AmazonResponseModel> RetrieveApiResultAsync(string searchValue)
{
..logic to call the api..
string responseBody = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<AmazonResponseModel>(responseBody);
}
}
, как вы можете видеть,поправьте меня, если архитектура неверна, здесь в качестве обобщений используется AmazonResponseModel .Как вы можете себе представить, AmazonApi и AppleApi возвращают 2 разные модели.Вот почему мой абстрактный родительский класс ApiHttpCaller использует обобщенные значения T , которые в спецификации AmazonApiCaller становятся AmazonResponseModel .Такие API вызываются из моего контроллера.
[Route("api/[controller]")]
[ApiController]
public class ItemsController<T> : ControllerBase
{
private readonly IEnumerable<ApiHttpCaller<T>> _apiCallers;
[HttpPost]
public async Task<ActionResult> Post([FromBody] string value)
{
var amazonCaller = _apiCallers.First(x => x.GetType() == typeof(AmazonApiCaller));
var itemResult = await amazonCaller.RetrieveApiResultAsync(value);
..more logic to map the itemResult to a viewModel..
}
}
Итак, первый вопрос: считаете ли вы правильным использование genercis T в контроллере, который затем становится специфическим типом внутри каждогоapi caller?
Второе и более важное: я не знаю, как зарегистрировать в Startup.cs ApiHttpCallers таким образом, чтобы они правильно вводились в мой контроллер.Первое предположение таково:
services.AddSingleton<ApiCaller<T>, AmazonApiCaller<AmazonResponseModel>>();
services.AddSingleton<ApiCaller<T>, AppleApiCaller<AppleResponseModel>>();
Дело в том, что Startup.cs ничего не знает о T .