DI ILogger с Serilog на Webapi 2 под управлением Asp.Net Core 2 - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь интегрировать Serilog в мой WebApi 2 с Asp.Net Core 2 (с интеграцией MSSQLServer).

Я добавил пакеты nuget, а затем добавил в свой

следующее

public async void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

var log = new LoggerConfiguration()
                .WriteTo.MSSqlServer(DbGlobals.DevDatabase, "Logs")
                .CreateLogger();

loggerFactory.AddSerilog(log);

В моем Program.cs есть значение по умолчанию;

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();

Из чтения документов MSDN .CreateDefaultBuilder(args) должно включать ведение журнала?

Однако, когда я тогда DI ILogger к моему контроллеру;

[Route("api/[controller]")]
public class TraderController : Controller
{
    private TraderService _service;
    private readonly ILogger _logger;

    public TraderController(Func<IBemfeitoDataContext> context, ILogger logger)
    {
        _service = new TraderService(context, logger);
        _logger = logger;
    }

Я получаю следующую ошибку;

InvalidOperationException: невозможно разрешить службу для типа & # x27; Microsoft.Extensions.Logging.ILogger & # x27; при попытке активировать & # x27; WebApi.Controllers.TraderContactController & # x27;.

Нужно ли физически настроить синглтон для ILogger в файле Startup.cs. Может кто-нибудь сказать мне, что мне здесь не хватает? Как я и предполагал, поскольку ведение журнала встроено в конвейер Core, это будет то, что он знает, как решить?

Ответы [ 2 ]

0 голосов
/ 19 июля 2018

Оба ILoggerFactory и общий ILogger<T> вводятся. Это означает, что ваш контроллер может быть таким:

   [Route("api/[controller]")]
   public class TraderController : Controller {
       private readonly ITraderService service;
       private readonly ILogger logger;
       public TraderController(ITraderService service, ILoggerFactory loggerFactory) 
       { 
           this.service = service;
           this.logger = loggerFactory.CreateLogger<TraderController>();
       }
       //...
   }
0 голосов
/ 26 апреля 2018

Вам необходимо провести рефакторинг контроллера, чтобы он ожидал универсального логгера ILogger<T>, который получен из ILogger

[Route("api/[controller]")]
public class TraderController : Controller {
    private TraderService _service;
    private readonly ILogger _logger;

    public TraderController(
            Func<IBemfeitoDataContext> context, 
            ILogger<TraderController> logger //<-- note the change here
    ) { 
        _service = new TraderService(context, logger);
        _logger = logger;
    }
}

ILogger<> отображается на Logger<>, когда .AddLogging() вызывается в CreateDefaultBuilder. ILogger не зарегистрирован непосредственно в коллекции услуг.

После того, как это было сделано, текущий выбор конструкции связи контроллера с проблемами реализации (т. Е. TraderService) стал причиной некоторой озабоченности.

исходя из того, как используется текущий код

public class TraderService : ITraderService {
    private readonly ILogger logger;

    public TraderService(Func<IBemfeitoDataContext> context, ILogger logger) {
        this.logger = logger;

        //...
    }

    //...code removed for brevity
}

услуга также должна быть исправлена ​​в зависимости от ILogger<T>

public class TraderService : ITraderService {
    private readonly ILogger logger;

    public TraderService(Func<IBemfeitoDataContext> context, ILogger<TraderService> logger) {
        this.logger = logger;
        //...
    }

    //...code removed for brevity
}

и контроллер должен быть реорганизован в зависимости от абстракции службы, а не от реализации.

[Route("api/[controller]")]
public class TraderController : Controller {
    private readonly ITraderService service;
    private readonly ILogger logger;

    public TraderController(ITraderService service, ILogger<TraderController> logger) { 
        this.service = service;
        this.logger = logger;
    }

    //...
}

Все участвующие классы получат свои зависимости в явном виде при разрешении.

В этом ответе предполагается, что ITraderService и TraderService зарегистрированы в контейнере DI.

...