В первой строке расширяющего метода в контейнер DI добавляется
ApiServiceSettings
. Во второй строке в контейнер DI добавляется
IApiServiceWrapper
и регистрируется класс с помощью фабрики
HTTPClient
. Это позволяет внедрять
IApiServiceWrapper
в другие классы, а фабрика
HTTPClient
будет управлять внедрением и временем существования
HTTPClient
:
public static IServiceCollection ConfigureApiServiceWrapper(this IServiceCollection
services, IConfiguration config)
{
<b> services.Configure<ApiServiceSettings>(</b>
<b> config.GetSection(nameof(ApiServiceSettings)));</b>
<b> services.AddHttpClient<IApiServiceWrapper,ApiServiceWrapper>();</b>
return services;
}
Откройте файл
Startup.cs
и добавьте следующий оператор
using
:
using AutoLot.Services.ApiWrapper;
Перейдите к методу
ConfigureServices()
и добавьте в него показанную ниже строку:
services.ConfigureApiServiceWrapper(Configuration);
Построение класса CarsController
Текущая версия
CarsController
жестко привязана к хранилищам в библиотеке доступа к данным. Следующая итерация
CarsController
для связи с базой данных будет применять оболочку службы. Переименуйте
CarsController
в
CarsDalController
(включая конструктор) и добавьте в каталог
Controllers
новый класс по имени
CarsController
. Код этого класса является практически точной копией
CarsController
, но они хранятся по отдельности с целью прояснения разницы между использованием хранилищ и службы.
На заметку! При работе с одной и той же базой данных вам редко придется применять вместе уровень доступа к данным и оболочку службы. Здесь показаны оба варианта, чтобы вы смогли решить, какой из них лучше подходит в вашей ситуации.
Приведите операторы
using
к следующему виду:
using System.Threading.Tasks;
using AutoLot.Dal.Repos.Interfaces;
using AutoLot.Models.Entities;
using AutoLot.Services.ApiWrapper;
using AutoLot.Services.Logging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
Далее сделайте класс открытым, унаследуйте его от
Controller
и добавьте атрибут
Route
. Создайте конструктор, который принимает экземпляры реализаций
IAutoLotServiceWrapper
и
IAppLogging
, после чего присвойте оба экземпляра переменным уровня класса. Вот начальный код:
namespace AutoLot.Mvc.Controllers
{
[Route("[controller]/[action]")]
public class CarsController : Controller
{
private readonly IApiServiceWrapper _serviceWrapper;
private readonly IAppLogging<CarsController> _logging;
public CarsController(IApiServiceWrapper serviceWrapper,
IAppLogging<CarsController>
logging)
{
_serviceWrapper = serviceWrapper;
_logging = logging;
}
}
Вспомогательный метод GetMakes()
Вспомогательный метод
GetMakes()
строит экземпляр
SelectList
со всеми записями
Make
в базе данных. Он использует
Id
в качестве значения и
Name
в качестве отображаемого текста:
internal async Task<SelectList> GetMakesAsync()=>
new SelectList(
await _serviceWrapper.GetMakesAsync(),
nameof(Make.Id),
nameof(Make.Name));
Вспомогательный метод GetOneCar()
Вспомогательный метод
GetOneCar()
получает одиночную запись
Car
:
internal async Task<Car> GetOneCarAsync(int? id)
=> !id.HasValue ? null : await _serviceWrapper.GetCarAsync(id.Value);
Открытые методы действий
Единственное отличие между открытыми методами действий в этом контроллере и аналогичными методами в
CarsDalController
связано с доступом к данным, а также с тем,что все методы определены как асинхронные. Поскольку вы уже понимаете, для чего предназначено то или иное действие, ниже приведены остальные методы, изменения в которых выделены полужирным:
[Route("/[controller]")]
[Route("/[controller]/[action]")]
public <b>async Task<IActionResult></b> Index()
=> View(<b>await _serviceWrapper.GetCarsAsync()</b>);
[HttpGet("{makeId}/{makeName}")]