如何将 appsettings.json 中的设置注入 ILoggerProvider?
How to inject settings from appsettings.json to an ILoggerProvider?
由于一些特殊要求,我正在实施自定义 ILogger<T>
,其中一项要求是在项目 appsettings.json
的 Logging
部分内有一个部分,具有该记录器的配置值。问题是,将这些设置注入记录器的正确方法(或好方法)是什么?我想我应该首先在相应的 ILoggerProvider
中注入这些设置,并让提供者使用这些设置实例化一个记录器,但我对如何在提供者中正确注入这些值感到困惑。
到目前为止,我在 Program.cs
中有这个:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging((context, logging) =>
{
logging.ClearProviders();
logging.AddConfiguration(context.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddProvider(new CustomLoggerProvider());
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
,appsettings.json
中的相关部分是:
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"CustomLogger": {
"Level": "Error",
"Url": "http://[URL]"
}
},
,provider实现如下:
[ProviderAlias("CustomLogger")]
public class CustomLoggerProvider : ILoggerProvider
{
private readonly Dictionary<string, CustomLogger> _loggers;
private readonly LogLevel _level;
private bool _already_disposed;
public LogLevel Level
{
get => _level;
}
public CustomLoggerProvider()
{
//Here's where I don't know what should I do to inject the proper config values
_level = LogLevel.Error;
}
public ILogger CreateLogger(string categoryName)
{
if (_loggers.ContainsKey(categoryName))
{
return _loggers[categoryName];
}
var l = new CustomLogger(this);
_loggers.Add(categoryName, l);
return l;
}
// Rest of implementation omitted for simplicity
}
我找到了一个可接受的答案,我会 post 放在这里,以备不时之需。
步骤是:
- 实施您的
ILoggerProvider
和 ILogger
。 Microsoft 页面上的示例是一个很好的指南。
- 让您的
ILoggerProvider
实现在其构造函数上接受所需的设置(通过 IOptions<T>
或简单参数;我正在使用一个名为 MyCustomLoggerSettings
的选项对象)。
- 在
Startup.ConfigureServices()
中将您的 ILoggerProvider
注册为单例,如下所示(假设我的实现称为 MyCustomLoggerProvider
):
services.AddSingleton<ILoggerProvider>(p =>
{
var options = p.GetService<IOptions<MyCustomLoggerSettings>>();
return new MyCustomLoggerProvider(options);
});
完成。
作为奖励,通过这种方式,您可以将任何其他依赖项传递给该对象(包括在服务集合上注册的对象;services
中接受匿名函数的方法重载的使用为您提供服务集合作为参数,在那里你可以使用 GetService<T>
来解决任何依赖关系。
由于一些特殊要求,我正在实施自定义 ILogger<T>
,其中一项要求是在项目 appsettings.json
的 Logging
部分内有一个部分,具有该记录器的配置值。问题是,将这些设置注入记录器的正确方法(或好方法)是什么?我想我应该首先在相应的 ILoggerProvider
中注入这些设置,并让提供者使用这些设置实例化一个记录器,但我对如何在提供者中正确注入这些值感到困惑。
到目前为止,我在 Program.cs
中有这个:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging((context, logging) =>
{
logging.ClearProviders();
logging.AddConfiguration(context.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddProvider(new CustomLoggerProvider());
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
,appsettings.json
中的相关部分是:
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"CustomLogger": {
"Level": "Error",
"Url": "http://[URL]"
}
},
,provider实现如下:
[ProviderAlias("CustomLogger")]
public class CustomLoggerProvider : ILoggerProvider
{
private readonly Dictionary<string, CustomLogger> _loggers;
private readonly LogLevel _level;
private bool _already_disposed;
public LogLevel Level
{
get => _level;
}
public CustomLoggerProvider()
{
//Here's where I don't know what should I do to inject the proper config values
_level = LogLevel.Error;
}
public ILogger CreateLogger(string categoryName)
{
if (_loggers.ContainsKey(categoryName))
{
return _loggers[categoryName];
}
var l = new CustomLogger(this);
_loggers.Add(categoryName, l);
return l;
}
// Rest of implementation omitted for simplicity
}
我找到了一个可接受的答案,我会 post 放在这里,以备不时之需。
步骤是:
- 实施您的
ILoggerProvider
和ILogger
。 Microsoft 页面上的示例是一个很好的指南。 - 让您的
ILoggerProvider
实现在其构造函数上接受所需的设置(通过IOptions<T>
或简单参数;我正在使用一个名为MyCustomLoggerSettings
的选项对象)。 - 在
Startup.ConfigureServices()
中将您的ILoggerProvider
注册为单例,如下所示(假设我的实现称为MyCustomLoggerProvider
):
services.AddSingleton<ILoggerProvider>(p =>
{
var options = p.GetService<IOptions<MyCustomLoggerSettings>>();
return new MyCustomLoggerProvider(options);
});
完成。
作为奖励,通过这种方式,您可以将任何其他依赖项传递给该对象(包括在服务集合上注册的对象;services
中接受匿名函数的方法重载的使用为您提供服务集合作为参数,在那里你可以使用 GetService<T>
来解决任何依赖关系。