.Net Core 自定义记录器循环依赖注入参考/无限循环



我试图编写一个依赖于 ILogger :) 的服务的客户 ILogger/ILoggerProvider 这给我留下了一个循环引用和一个无限循环。

如何修改此代码以避免循环引用?

class Program
{
static void Main(string[] args)
{
var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton<IDependentOnLoggerService, MyService>();
serviceCollection.AddLogging(loggingBuilder =>
{
loggingBuilder.AddConfiguration(configuration.GetSection("Logging"));
loggingBuilder.AddConsole();
});
serviceCollection.AddCustomLogger();
using (var serviceProvider = serviceCollection.BuildServiceProvider())
{
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("hello world");
}
}
}
public interface IDependentOnLoggerService
{
void DoWork();
}
public class MyService : IDependentOnLoggerService
{
private ILogger logger;
public MyService(ILoggerFactory loggerFactory)
{
this.logger = loggerFactory.CreateLogger<MyService>();
this.logger.LogInformation("MyService create");
}
public void DoWork()
{
this.logger.LogInformation("Doing work");
}
}
public static class ServiceCollectionExtensions
{
public static void AddCustomLogger(this IServiceCollection serviceCollection)
{
serviceCollection.AddLogging(loggingBuilder =>
{
loggingBuilder.AddCustomLogger();
});
}
private static ILoggingBuilder AddCustomLogger(this ILoggingBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, CustomLoggerProvider>(
serviceProvider =>
{
// this causes circulation dependency injection, resolving IDependentOnLoggerService will try to resolve an ILogger which will bring it right back here
var loggerDependentService = serviceProvider.GetService<IDependentOnLoggerService>(); 
return new CustomLoggerProvider(loggerDependentService);
}));
return builder;
}
}
public class CustomLoggerProvider : ILoggerProvider
{
IDependentOnLoggerService dependentOnLoggerService;
public CustomLoggerProvider(IDependentOnLoggerService dependentOnLoggerService)
{
this.dependentOnLoggerService = dependentOnLoggerService;
}
public ILogger CreateLogger(string categoryName)
{
return new CustomLogger(this.dependentOnLoggerService);
}
public void Dispose() { }
}
public class CustomLogger : ILogger
{
IDependentOnLoggerService dependentOnLoggerService;
public CustomLogger(IDependentOnLoggerService dependentOnLoggerService)
{
this.dependentOnLoggerService = dependentOnLoggerService;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
this.dependentOnLoggerService.DoWork();
Console.WriteLine(state.ToString());
}
}

如果可能的话,我想保持结构相似,而不是用通用主机和 IHostBuilder 重写。

你可以有第三个类来引用这两个服务,你只需要在需要服务的地方依赖注入这个类。

这里有一个类似的问题,你可以看看。

最新更新