繁体   English   中英

如何将依赖项注入 asp.net core 2.0 中的自定义 ILogger?

[英]How can I inject dependencies into a custom ILogger in asp.net core 2.0?

在 asp.net core 1.1 中,我可以将 IServiceProvider 注入记录器提供程序并在调用CreateLogger时解析我的记录器,但在 asp.net core 2.0 中这一切都发生了变化

我的 ILogger 实现需要注入依赖项。 我怎样才能做到这一点?

ASP.NET核心提供了可能性,以取代内置自定义一个DI容器(见文章详细信息)。 您可以使用这种可能性来获取IServiceProvider实例,以便在仍然使用标准 .Net 核心 DI 容器的同时进行记录引导。

为此,您应该将Startup.ConfigureServices(IServiceCollection services)方法的返回值从 void 更改为IServiceProvider 您可以使用这种可能性在 ConfigureServices 中构建 IServiceProvider 的实例,将其用于记录引导,然后从该方法返回。

示例代码:

public interface ISomeDependency
{
}

public class SomeDependency : ISomeDependency
{
}

public class CustomLogger : ILogger
{
    public CustomLogger(ISomeDependency dependency)
    {
    }

    //  ...
}

public class CustomLoggerProvider : ILoggerProvider
{
    private readonly IServiceProvider serviceProvider;

    public CustomLoggerProvider(IServiceProvider serviceProvider)
    {
        this.serviceProvider = serviceProvider;
    }

    public ILogger CreateLogger(string categoryName)
    {
        return serviceProvider.GetRequiredService<ILogger>();
    }

    //  ...
}

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        return ConfigureLogging(services);
    }

    private IServiceProvider ConfigureLogging(IServiceCollection services)
    {
        services.AddTransient<ISomeDependency, SomeDependency>();
        services.AddSingleton<ILogger, CustomLogger>();
        IServiceProvider serviceProvider = services.BuildServiceProvider();

        var loggerFactory = new LoggerFactory();
        loggerFactory.AddProvider(new CustomLoggerProvider(serviceProvider));

        return serviceProvider;
    }

    //  ...
}

如果您在 program.cs 中配置日志记录,您可以创建一个函数来配置日志记录并获取日志记录提供程序的实例,如下所示:

private static void ConfigureApplicationLogging(WebHostBuilderContext context, ILoggingBuilder loggingBuilder)
    {
        loggingBuilder.AddConfiguration(context.Configuration.GetSection("Logging"));
        loggingBuilder.AddDebug();
        loggingBuilder.AddConsole();

        var serviceProvider = loggingBuilder.Services.BuildServiceProvider();
        loggingBuilder.AddProvider(new DoxErrorLoggerProvider(serviceProvider, null));
    }

然后在 BuildWebHost 中,您将按如下方式配置日志记录:

        public static IWebHost BuildWebHost(string[] args) =>            
        WebHost.CreateDefaultBuilder(args)
            .ConfigureLogging(ConfigureApplicationLogging)
            .UseNLog()
            .UseStartup<Startup>()
            .Build();

从你在不同地方需要的那个依赖开始

public class SomeDependency : ISomeDependency
{
}

一个扩展文件,因此我们可以根据 MSDN 在 ServiceCollection 上配置日志记录 您可以在各种来源上找到相当标准的东西

public static class ApplicationLoggerFactoryExtensions
{
    public static ILoggingBuilder CustomLogger(this ILoggingBuilder builder)
    {
        builder.Services.AddSingleton<ILoggerProvider, CustomLoggerProvider>();
        //Be careful here. Singleton may not be OK for multi tenant applications - You can try and use Transient instead.
        return builder;
    }
}

记录器提供程序是在您处理业务代码并需要记录内容时构建服务调用的部分。

因此,在应用程序的上下文中,DI 在此处构建并可用。 现在为什么ILoggerProvider现在存在可能是有道理的。

public class CustomLoggerProvider : ILoggerProvider
{
    private ISomeDependency someDependency;

    public CustomLoggerProvider(ISomeDependency someDependency)
    {
        this.someDependency = someDependency;
    }

    public ILogger CreateLogger(string categoryName)
    {
        return new CustomeLogger(someDependency);
    }
}

具体的自定义记录器非常简单的东西

public class CustomLogger : ILogger
{
    public CustomLogger(ISomeDependency dependency)
    {
    }
}

并且在您配置 ServiceCollection 的地方.. 就像在 Startup.cs 中的 OP 问题一样

private void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<ISomeDependency, SomeDependency>();

    //services.AddSingleton<ILogger, CustomLogger>(); <== NO

    var loggerFactory = new LoggerFactory(); //??? newer DotNet gives you LoggerFactory in startup this may be unnecessary.

   //Add some console printer
   services.AddLogging(configure => configure.AddConsole())
               .Configure<LoggerFilterOptions>(options => options.MinLevel = LogLevel.Trace);

    //Add our custom logger
    services.AddLogging(configure => configure.CustomLogger()); // <== our extension helping out!
}

所以只是 ILogger 的使用说明

✘ 不要 - 不要在您的服务中添加任何 ILogger

LoggerFactoryLoggerProvider配置的重点是简化使用ILogger

public MyBusinessService(ILogger<BusinessServiceClass> log)
{
  log.Information("Please tell all registered loggers I am logging!);
}

在我的示例中,它将向控制台打印消息(如果可用)以及接受我们注入的依赖项的 CustomLogger。 如果你注册更多..它会去所有人

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM