简单注入器:注册ILogger< T>通过使用ILoggerFactory.CreateLogger< T>() [英] Simple Injector: Register ILogger<T> by using ILoggerFactory.CreateLogger<T>()

查看:613
本文介绍了简单注入器:注册ILogger< T>通过使用ILoggerFactory.CreateLogger< T>()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working with a project which utilizes Simple Injector as dependency injector. On the other hand, this project uses Microsoft.Extensions.Logging in order to log the events that occurs in certain classes.

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

My technical issue is pretty simple to explain. I want to register in my DI the ILogger independently of the class T which is being invoked, but I DO NEED to do it from my ILoggerFactory.CreateLogger<T>() method because this gets the logger configuration using Microsoft.Extensions.Configuration.

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

I need to use something like this in order to instance my logger:

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

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

I could achieve the injection by doing:

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

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

And this allows us to resolve something like:

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 类获得的配置,因此这没有用。

But as I said, this does it without passing through the configuration obtained from the Microsoft.Extensions.Logging.ILoggerFactory class, so this isn't useful.


是否可以使用我的 CreateLogger< T> ILogger< T> c>?

Is there a way to register ILogger<T> by using my CreateLogger<T>?


推荐答案

使用以下注册:

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

或者,如果要将Simple Injector集成到通用主机或ASP.NET Core应用程序中,请使用<一个href = https://simpleinjector.org/servicecollection+logging rel = nofollow noreferrer>。AddLogging()扩展方法甚至可以注入一个非通用的 ILogger 放入您的应用程序组件中,如以下ASP.NET Core Startup 类所示:

Or, in case you are integrating Simple Injector into a generic host or ASP.NET Core application, make use of the .AddLogging() extension method to even inject a non-generic ILogger into your application components, as demonstrates in this ASP.NET Core Startup class:

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和ASP.NET Core MVC集成指南

让应用程序组件依赖于 ILogger 而不是 ILogger< T> ,这使您的代码更简单,更易于测试,并且错误更少。如果您使用的是不带服务集合集成的Simple Injector(如前面的示例所示,则可以使用以下注册使Simple Injector确保在每次注入 ILogger 时仍然注入正确的 Logger< T>

Letting application components depend on ILogger instead of ILogger<T>, makes your code simpler, easier to test, and less error prone. If you're using Simple Injector without Service Collection integration (as the previous example showed, you can use the following registration to let Simple Injector ensure the correct Logger<T> is still injected whenever an ILogger is injected:

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

这可确保每个应用程序组件都有自己的 Logger< T> 实例,其中 T 是类型记录器所注入的组件的示例。下面的类取决于 ILogger

This ensures that every application component gets its own Logger<T> instance, where T is the type of the component the logger is injected into. Take the following class for example that depends on ILogger:

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

上述注册将确保 ComponentA 注入了 Logger< ComponentA> ,即使它仅依赖于 ILogger ,而不是在 ILogger< T> 上。

The above registration will ensure that ComponentA is injected with a Logger<ComponentA>, even though it simply depends on ILogger and not on ILogger<T>.

如果上述内容适合您,您可以在这里停止阅读。 。或继续阅读,如果您对更多SOLID解决方案感兴趣。

You can stop reading here if the above suits your needs... or continue reading if you're interested in a more SOLID solution.

而不是让应用程序组件依赖于框架-定义了 ILogger 抽象,您还可以选择定义特定于应用程序的记录器抽象,如依赖关系反转原理(DIP)。

Instead of letting application components depend on the framework-defined ILogger abstraction, you could also choose to define an application-specific logger abstraction, as prescribed by the Dependency Inversion Principle (DIP).

DIP指出抽象应该由应用程序本身定义-这意味着您定义了自己的自己的记录器抽象(另请参见解释为什么要这样做),并首先构建一个适配器,类似于所述此处。您可以简单地从描述的 MicrosoftLoggingAdapter 派生通用适配器,如下所示:

The DIP states that abstractions should be defined by the application itself—this means you define your own logger abstraction (also see this for an explanation of why you want to do this) and on top of that you build an adapter, much like described here. You can simply derive your generic adapter from the described MicrosoftLoggingAdapter as follows:

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

使用该通用适配器,您可以按以下方式配置简单注入器:

Using this generic adapter, you can configure Simple Injector as follows:

container.RegisterInstance<ILoggerFactory>(factory);

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

这篇关于简单注入器:注册ILogger&lt; T&gt;通过使用ILoggerFactory.CreateLogger&lt; T&gt;()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆