Создание базового контроллера для ядра ASP.NET для ведения журнала, но что-то не так с моей подписью конструктора?
Я хочу иметь простой способ, чтобы все контроллеры веб-api автоматически регистрировали то, что они делают, без явного указания этого. Почему это неправильно? Кроме того, есть ли способы лучше?
public class BaseController<T> : ControllerBase where T: BaseController<T>
{
private readonly IAppLogger<T> _logger;
public BaseController(IAppLogger<T> logger)
{
_logger = logger;
}
}
[Route("api/[controller]")]
[ApiController]
public class RfReportTypeController : BaseController<RfReportTypeController>
{
private readonly IRfReportTypeService _rfReportTypeService;
public RfReportTypeController(IRfReportTypeService rfReportTypeService)
{
_rfReportTypeService = rfReportTypeService ?? throw new ArgumentNullException(nameof(rfReportTypeService));
}
}
Код серьезности Описание Ошибка состояния подавления строки файла проекта CS7036 Не указан аргумент, соответствующий обязательному формальному параметру 'logger'
BaseController<RfReportTypeController>.BaseController(IAppLogger<RfReportTypeController>)
PWDRS.WebAPI C:\Users\M3MAH02\source\repos\PWDRS\PWDRS\PWDRS.WebAPI\Controllers\RfReportTypeController.cs 17 Активно
3 ответа
Необходимо передать параметры, требуемые базовым конструктором
[Route("api/[controller]")]
[ApiController]
public class RfReportTypeController : BaseController<RfReportTypeController>
{
private readonly IRfReportTypeService _rfReportTypeService;
public RfReportTypeController(
IRfReportTypeService rfReportTypeService,
IAppLogger<RfReportTypeController> logger //<--NOTE THIS
) : base(logger) //<-- NOTE THIS
{
_rfReportTypeService = rfReportTypeService ?? throw new ArgumentNullException(nameof(rfReportTypeService));
}
}
Принятый ответ сделает все ваши контроллеры тесно связанными с регистратором и уменьшит цель наличия базового контроллера. Я бы предложил следующее решение
[Route("api/[controller]")]
[ApiController]
public abstract class BaseController<T> : ControllerBase
{
private IAppLogger<T> _logger;
protected IAppLogger<T> Logger=> _logger ??= HttpContext.RequestServices.GetService<IAppLogger<T>>();
}
public class RfReportTypeController : BaseController<RfReportTypeController>
{
private readonly IRfReportTypeService _rfReportTypeService;
public RfReportTypeController(IRfReportTypeService rfReportTypeService)
{
_rfReportTypeService = rfReportTypeService ?? throw new ArgumentNullException(nameof(rfReportTypeService));
}
}
В ответ на ответ @Mohamed Salman: Атрибуты [Route ()] и [ApiController] не следует помещать в BaseController, поскольку это больше не будет точкой маршрутизации. Этот базовый контроллер будет унаследован с разными контроллерами api, и именно они будут использовать атрибуты [Route ()] и [ApiController].
Пожалуйста, проверьте новый измененный исходный образец ниже:
public abstract class BaseController<T> : ControllerBase
{
private IAppLogger<T> _logger;
protected IAppLogger<T> Logger=> _logger ??= HttpContext.RequestServices.GetService<IAppLogger<T>>();
}
[Route("api/[controller]")]
[ApiController]
public class RfReportTypeController : BaseController<RfReportTypeController>
{
private readonly IRfReportTypeService _rfReportTypeService;
public RfReportTypeController(IRfReportTypeService rfReportTypeService)
{
_rfReportTypeService = rfReportTypeService ?? throw new ArgumentNullException(nameof(rfReportTypeService));
}
}