У меня настроен Serilog для Asp.Net Core 2.0, и он отлично работает через внедрение зависимостей .Net Core в моем стартовом веб-проекте (если я использую его через Microsoft.Extensions.Logging), но я не могу получить к нему доступ из любого другого проекта.
Вот что у меня есть:
Program.cs
using System;
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
namespace ObApp.Web.Mvc
{
public class Program
{
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
.Build();
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.CreateLogger();
try
{
Log.Warning("Starting BuildWebHost");
BuildWebHost(args).Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseSerilog()
.Build();
}
}
Startup.cs
Запуск .cs по умолчанию. Я никоим образом не изменил его по сравнению с оригинальным шаблоном для нового проекта Asp.Net Core MVC.
Я подумал, что мне может понадобиться добавить Serilog в сервисы IServiceCollection, но статья Leaner, подлая регистрация в ASP.NET Core 2 по адресу https://nblumhardt.com/2017/08/use-serilog/, говорит мне, что в этом нет необходимости.
Затем вы можете удалить любую другую конфигурацию регистратора, которая висит вокруг: нет необходимости в разделе "Ведение журнала" в appsettings.json, нигде нет AddLogging() и нет конфигурации через ILoggerFactory в Startup.cs.
UseSerilog() заменяет встроенный ILoggerFactory, так что каждый регистратор в вашем приложении, будь то класс Serilogs Log, Serilogs ILogger или Microsoft.Extensions.Logging.ILogger, будет поддерживаться одной и той же реализацией Serilog и управляться через одну и ту же конфигурацию,
Что я ожидал
Возможность просто внедрить регистратор через конструктор в любом классе в любом проекте в решении. Например:
using Serilog;
public MyTestClass(ILogger logger) { ... }
What я Got - Веб (Startup) проект
Инжекция работает в HomeController, если я использую оболочку Microsoft.Extensions.Logging:
using Microsoft.Extensions.Logging;
public class HomeController : Controller
{
ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
_logger.LogDebug("Controller instantiated.");
}
}
Внедрение не выполняется в любом проекте/классе, если я пытаюсь внедрить Serilog.ILogger
using Serilog;
using Serilog.Extensions.Logging; // Not sure if this would help.
public class HomeController : Controller
{
ILogger _logger;
public HomeController(ILogger logger)
{
_logger = logger;
_logger.Debug("Controller instantiated.");
}
}
InvalidOperationException: невозможно разрешить службу для типа "Serilog.ILogger" при попытке активировать "ObApp2.Web.Mvc.Controllers.HomeController".
Моя большая проблема - другие проекты
Моя большая проблема заключается в том, что я не могу получить регистратор через DI с помощью любого метода, который я пробовал, если я работаю в другом проекте в решении.
Когда я пытаюсь внедрить либо используя Microsoft.Extensions.Logging или Serilog, я получаю исключение отсутствующего параметра во время сборки.
using Microsoft.Extensions.Logging;
namespace ObApp.Domain
{
public class MyTestClass(ILogger<MyTestClass> logger) { ... }
- or -
using Serilog;
namespace ObApp.Domain
{
public class MyTestClass(ILogger logger) { ... }
Оба генерируют ошибку сборки, похожую на:
Отсутствует аргумент, который соответствует обязательному формальному параметру 'logger' в MyTestClass.MyTestClass(ILogger).
Вопросы
-
При внедрении с этим типом конфигурации Serilog рекомендуется ли ссылаться на Microsoft.Extensions.Logging или Serilog в файлах классов, где я делаю инъекцию?
-
Как я могу заставить DI работать через все проекты?