如何将依赖项传递给自定义.NET Core ILoggerProvider [英] How to pass dependencies to a custom .NET Core ILoggerProvider

查看:511
本文介绍了如何将依赖项传递给自定义.NET Core ILoggerProvider的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个自定义.NET Core ILoggerProvider,它需要一些依赖项才能传递到其构造函数中.

I am creating a custom .NET Core ILoggerProvider that requires some dependencies to be passed into its constructor.

我相信我正在使用一种相当通用的模式来初始化我的日志记录实现;看起来像这样:

I believe I am using a fairly common pattern to initialize my logging implementation; it looks something like this:

var services = new ServiceCollection();

// Register some services here

services.AddLogging(builder =>
{
    builder.AddProvider(new DebugLoggerProvider());
});

var provider = services.BuildServiceProvider();

我想以与当前添加DebugLoggerProvider相同的方式在AddLogging块中添加我的新提供程序.

I want to add my new provider within the AddLogging block, in the same way that the DebugLoggerProvider is currently added.

我的自定义提供程序要求将一些其他服务传递到其构造函数中,并且由于这些服务已经在ServiceCollection中注册,因此我假设我应该能够引用它们.但是,不同于像AddSingleton这样的方法,该方法具有暴露IServiceProvider的重载,而AddLogging似乎没有提供等效的方法.

My custom provider requires some other services to be passed into its constructor and since these are already registered with the ServiceCollection, I assume that I should be able to reference them. However, unlike methods such as AddSingleton, which have an overload that exposes the IServiceProvider, AddLogging doesn't seem to offer an equivalent.

是否有一种简单的方法来实现这一目标,或者我是否试图做一些与.NET Core日志记录设计部署方式相矛盾的事情?

Is there a simple way to achieve this, or am I attempting to do something that contradicts the way .NET Core logging was designed to be deployed?

更新:

尝试了@Nkosi提出的建议之后,我可以确认可以绕过AddLogging并直接实现其内部功能来使其正常工作,如下所示:

After experimenting with the suggestions proposed by @Nkosi, I can confirm that it is possible to get this to work by bypassing AddLogging and directly implementing what it does internally, as follows:

var services = new ServiceCollection();

// Register some services
services.AddSingleton<IMyService, MyService>();

// Initialize logging
services.AddOptions();
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddSingleton<ILoggerProvider>(p => new DebugLoggerProvider());
services.AddSingleton<ILoggerProvider>(p => new MyLoggerProvider("Constant value", p.GetService<IMyService>()));

var provider = services.BuildServiceProvider();

推荐答案

现在,我不确定是否已经有扩展程序可以执行此操作,但是我在这里看到了强大的功能.

Now I am not sure if an extension already exists to do this but I see potencial here.

首先,这是 AddProvider 在源代码存储库中定义.

First this is how AddProvider is defined in the source code repo.

public static ILoggingBuilder AddProvider(this ILoggingBuilder builder, ILoggerProvider provider) {
    builder.Services.AddSingleton(provider);
    return builder;
}

您可以通过制作自己的通用版本来建立

You could build up on that by making your own generic version

public static class MyLoggingBuilderExtensions {
    public static ILoggingBuilder AddProvider<T>(this ILoggingBuilder builder)
        where T: class, ILoggerProvider{
        builder.Services.AddSingleton<ILoggerProvider, T>();
        return builder;
    }
}

它应该允许DI容器在解析后建立对象图

which should allow the DI container to build up the object graph when resolved

services.AddLogging(builder =>
{
    builder.AddProvider<CustomLoggerProvider>();
});

还有扩展此功能的空间,例如添加您自己的重载以公开IServiceProvider并将其传递给扩展内的AddSingleton.

And there is room to extend this functionality, like adding your own overload that exposes the IServiceProvider and passing that on to the AddSingleton within the extension.

public static ILoggingBuilder AddProvider<T>(this ILoggingBuilder builder, Func<IServiceProvider, T> factory)
    where T: class, ILoggerProvider {
    builder.Services.AddSingleton<ILoggerProvider, T>(factory);
    return builder;
}

二手

services.AddLogging(builder => {
    builder.AddProvider<CustomLoggerProvider>(p => new CustomLoggerProvider("Constant value", p.GetService<IMyService>()));
});

这篇关于如何将依赖项传递给自定义.NET Core ILoggerProvider的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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