У меня есть ApplicationDbContext.
Поставщик журналов:
Код: Выделить всё
[ProviderAlias("Database")]
public class DatabaseLoggerProvider : ILoggerProvider
{
private readonly IDisposable? _onChangeToken;
private DatabaseLoggerOptions _currentConfig;
private readonly ConcurrentDictionary _loggers = new(StringComparer.OrdinalIgnoreCase);
private readonly IServiceProvider _serviceProvider;
public DatabaseLoggerProvider(IOptionsMonitor config, IServiceProvider serviceProvider)
{
_onChangeToken = config.OnChange(updatedConfig => _currentConfig = updatedConfig);
_currentConfig = config.CurrentValue;
_serviceProvider = serviceProvider;
}
public ILogger CreateLogger(string categoryName) =>
_loggers.GetOrAdd(categoryName, name => new(name, GetCurrentConfig, _serviceProvider));
private DatabaseLoggerOptions GetCurrentConfig() => _currentConfig;
public void Dispose()
{
_onChangeToken?.Dispose();
GC.SuppressFinalize(this);
}
}
Код: Выделить всё
internal class DatabaseLogger(string category, Func getCurrentConfiguration, IServiceProvider serviceProvider) : ILogger
{
private class ScopeDisposable(Action disposeAction) : IDisposable
{
private readonly Action _disposeAction = disposeAction;
public void Dispose()
{
_disposeAction.Invoke();
}
}
private readonly object _lock = new();
private readonly AsyncLocal _scopeData = new();
private readonly IServiceProvider _serviceProvider = serviceProvider;
public IDisposable? BeginScope(TState state) where TState : notnull
{
if (state is DatabaseLoggerParameters scopeData)
_scopeData.Value = scopeData;
// Return a disposable object to end the scope when disposed.
return new ScopeDisposable(() => _scopeData.Value = default);
}
public bool IsEnabled(LogLevel logLevel)
{
return (getCurrentConfiguration().CategoryToLogLevel.TryGetValue(category, out LogLevel value) ? value :
getCurrentConfiguration().CategoryToLogLevel.GetValueOrDefault("Default"))
Подробнее здесь: [url]https://stackoverflow.com/questions/78254552/how-to-inject-dbcontext-into-ilogger-for-custom-database-logging-provider[/url]