gpt4 book ai didi

c# - 简单注入(inject)器 : Register ILogger by using ILoggerFactory. CreateLogger()

转载 作者:可可西里 更新时间:2023-11-01 08:15:26 24 4
gpt4 key购买 nike

我正在处理一个使用简单注入(inject)器作为依赖注入(inject)器的项目。另一方面,该项目使用 Microsoft.Extensions.Logging 来记录某些类中发生的事件。

我的技术问题很容易解释。我想在我的 DI 中独立于正在调用的类 T 注册 ILogger,但是我确实需要从我的 ILoggerFactory.CreateLogger<T>() 中完成它方法,因为这会使用 Microsoft.Extensions.Configuration 获取记录器配置.

我需要使用这样的东西来实例化我的记录器:

private Microsoft.Extensions.Logging.ILogger CreateLogger<T>()
{
var factory = this.ResolveService<ILoggerFactory>();
var logger = factory.CreateLogger<T>();
return logger;
}

我可以通过以下方式实现注入(inject):

Container.Register(typeof(ILogger<>), typeof(Logger<>));

这使我们能够解决以下问题:

public class SomeApiController : ApiController
{
public SomeApiController(ILogger<SomeApiController> logger)
{
//logger is well instantiated, but doesn't got the configuration
logger.LogInformation("test log.");
}
}

但正如我所说,这样做并没有通过从 Microsoft.Extensions.Logging.ILoggerFactory 获得的配置。类,所以这没有用。

有没有办法注册ILogger<T>通过使用我的 CreateLogger<T> ?

最佳答案

使用以下注册:

container.RegisterInstance<ILoggerFactory>(loggerFactory);
container.RegisterSingleton(typeof(ILogger<>), typeof(Logger<>));

或者,如果您将 Simple Injector 集成到通用主机或 ASP.NET Core 应用程序中,请使用 .AddLogging()甚至注入(inject)非泛型的扩展方法 ILogger进入您的应用程序组件,如本 ASP.NET Core Startup 中所示类:

public class Startup
{
...

public void ConfigureServices(IServiceCollection services)
{
services.AddLogging(); // Adds logging to the framework

// AddSimpleInjector enables "cross wiring," which means you can let
// Simple Injector-resolved components to depend on the generic
// ILogger<T> abstraction.
services.AddSimpleInjector(container, options =>
{
options.AddAspNetCore();

// AddLogger allows Simple Injector-resolved components to depend on
// the non-generic Microsoft.Extensions.Logging.ILogger interface.
// Simple Injector will automatically inject the correct ILogger<T>
// for you.
options.AddLogging();
});
}

...
}

有关完整示例,请参阅 ASP.NET Core and ASP.NET Core MVC Integration Guide .

让应用程序组件依赖ILogger而不是 ILogger<T> ,使您的代码更简单,更易于测试,并且不易出错。如果您使用的是不带 Service Collection integration 的简单注入(inject)器(如前面的示例所示,您可以使用以下注册让 Simple Injector 确保在注入(inject) Logger<T> 时仍然注入(inject)正确的 ILogger:

container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
_ => true);

这确保每个应用程序组件都有自己的 Logger<T>实例,其中 T是记录器注入(inject)的组件的类型。下面以依赖ILogger的类为例:

public class ComponentA : IService
{
public ComponentA(ILogger logger) { ... }
}

以上注册将确保ComponentA注入(inject)了 Logger<ComponentA> ,即使它仅取决于 ILogger而不是 ILogger<T> .

如果以上内容满足您的需要,您可以在此处停止阅读……或者如果您对更可靠的解决方案感兴趣,请继续阅读。

可靠的解决方案

而不是让应用程序组件依赖于框架定义的 ILogger抽象,您还可以选择定义特定于应用程序的记录器抽象,如 Dependency Inversion Principle 所规定的那样(DIP).

DIP 声明抽象应由应用程序本身定义——这意味着您可以定义自己的 logger abstraction (另请参阅 this 以了解您为什么要这样做的解释)并在此基础上构建一个适配器,就像描​​述的 here 一样。 .您可以简单地从描述的 MicrosoftLoggingAdapter 派生您的通用适配器。如下:

public sealed class MicrosoftLoggingAdapter<T> : MicrosoftLoggingAdapter 
{
public MicrosoftLoggingAdapter(ILoggerFactory factory)
: base(factory.CreateLogger<T>()) { }
}

使用这个通用适配器,您可以按如下方式配置 Simple Injector:

container.RegisterInstance<ILoggerFactory>(factory);

container.RegisterConditional(
typeof(MyApplication.Abstractions.ILogger),
c => typeof(MicrosoftLoggingAdapter<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
_ => true);

关于c# - 简单注入(inject)器 : Register ILogger<T> by using ILoggerFactory. CreateLogger<T>(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41243485/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com