在我的定制ConsoleFormatter
中,我需要从添加到DI的服务中获取一个值.该值保存在作用域服务中,因为它 for each 新请求生成一个新值,但应该在请求期间保留该值.
问题是我不知道如何访问ConsoleFormatter
中的DI服务,我在下面try 的是将服务容器放入选项参数中.我在这里的 idea 是.NET服务是一个单例,这样我就可以在登录时请求我的服务并获得我的作用域服务.
public static class ConsoleLoggerExtensions
{
public static ILoggingBuilder AddCustomConsoleFormatter(
this ILoggingBuilder builder, Action<CustomConsoleFormatterOptions> options)
{
return builder.AddConsole(
options => options.FormatterName = nameof(CustomLoggingFormatter))
.AddConsoleFormatter<
CustomLoggingFormatter, CustomConsoleFormatterOptions>(
options);
}
}
public sealed class CustomConsoleFormatterOptions : ConsoleFormatterOptions
{
public IServiceProvider serviceProvider { get; set; }
}
public sealed class CustomLoggingFormatter : ConsoleFormatter, IDisposable
{
static long RowIndex = 1;
readonly IDisposable _optionsReloadToken;
CustomConsoleFormatterOptions _formatterOptions;
public CustomLoggingFormatter(
IOptionsMonitor<CustomConsoleFormatterOptions> options)
: base(nameof(SebLoggingFormatter))
{
(_optionsReloadToken, _formatterOptions) =
(options.OnChange(ReloadLoggerOptions), options.CurrentValue);
}
public override void Write<TState>(in LogEntry<TState> logEntry,
IExternalScopeProvider scopeProvider, TextWriter textWriter)
{
string message =
logEntry.Formatter?.Invoke(logEntry.State, logEntry.Exception);
if (message is null)
return;
var idService =
_formatterOptions.serviceProvider.GetService<IIdService>();
var requestId = idService.RequestId;
}
void ReloadLoggerOptions(CustomConsoleFormatterOptions options) =>
_formatterOptions = options;
public void Dispose() =>
_optionsReloadToken?.Dispose();
}
在我的初创公司中,我添加了一个任务来获取CustomFormnaytterOptions
services.AddLogging(opt => opt.AddCustomConsoleFormatter(options =>
{
var serviceProvider = services.BuildServiceProvider();
options.serviceProvider = serviceProvider;
}));
但是,当我从服务请求IdService时,我得到的是一个空值的服务,对我来说,这可能是因为:
- 无Http上下文(IdService正在通过当前请求中的标头拾取或创建ID)
- 我在这里使用的.Net服务是启动时的旧服务(=不是单例),因此与当前请求无关
我不理解的一件事是,(ConsoleFormatterOptions使用的).Net中的选项编码模式似乎是一个内置的功能.我应该以某种方式try 使选项无效,以便它从启动时重新运行任务吗?