Создание базового контроллера для ядра 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));
    }
}
Другие вопросы по тегам