#c# #asp.net-core #serilog
Вопрос:
Я искал возможность интегрировать Serilog в новую реализацию API с использованием net core 5. Насколько я понимаю, это работает так, что он переопределяет базовую реализацию ILogger и добавляет дополнительные функции, которые все хороши и работают так, как ожидалось.
Проблема, с которой я сталкиваюсь, заключается в том, что даже без указания реализации ведения журнала в моем запуске зависимость ILogger от контроллеров никогда не бывает нулевой. Хотя этот вопрос может показаться странным, я пытаюсь понять, откуда взялся этот экземпляр ILogger по умолчанию.
Проблему можно воспроизвести, создав новый API net core 5 в Visual Studio, с помощью которого можно получить пример контроллера погоды и один метод Get (). В этом примере контроллер имеет зависимость ILogger в конструкторе, как показано ниже;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
Который затем может быть использован в действии;
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
_logger.LogInformation("Testing");
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
В примере приведены следующие файлы program.cs и startup.cs;
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication2", Version = "v1" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication2 v1"));
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Нигде в этом коде мы, похоже, не добавляем/определяем регистратор, и я пытаюсь понять, откуда это взялось.
В моей собственной реализации у меня есть зависимость от ILogger в других классах, которая работает в контексте вызова из API, но терпит неудачу при вызове с помощью модульного теста, как (в настоящее время) Я явно не определяю ILogger в приспособлении.
Итак, где же ILogger инициализируется в примере API?
Примеры других API имеют следующий код в конструкторе, но если logger никогда не имеет значения null, то…..
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
Комментарии:
1.
ILogger<T>
это из инфраструктуры ведения журнала, которая автоматически вводится хостом, созданным сHost.CreateDefaultBuilder
помощью . Вы можете увидеть более подробную информацию здесь: docs.microsoft.com/en-us/aspnet/core/fundamentals/host/…2. Кроме того, контейнер DI в .NET Core не может вводить
null
, поэтомуnull
проверка полезна только в том случае, если вы хотите переключиться на другую систему DI, которая вводит значение null для отсутствующих служб3. @CamiloTerevinto Идеально, спасибо
Ответ №1:
Вызов Host.CreateDefaultBuilder
добавляет значения по умолчанию для ведения журнала. Чтобы удалить эти значения по умолчанию, вы можете сделать это:
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
// Add your own logging provider here.
})
Более подробную информацию можно найти здесь: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-5.0
Комментарии:
1. Удаление поставщиков не удаляет экземпляр ILogger, это просто означает, что коллекция регистраторов пуста, и, хотя при попытке внести что-либо в журнал не генерируется никаких исключений, записи в журнале не создаются.