为什么 .NET Core DI 容器不注入 ILogger? [英] Why does .NET Core DI container not inject ILogger?

查看:27
本文介绍了为什么 .NET Core DI 容器不注入 ILogger?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在基于 .NET Core 2.1 的 C# 控制台应用程序中进行登录和运行.

I am trying to get logging up and running in my C# console app based on .NET Core 2.1.

我在 DI 声明中添加了以下代码:

I added the following code to my DI declaration:

var sc = new ServiceCollection();

sc.AddLogging(builder =>
{
    builder.AddFilter("Microsoft", LogLevel.Warning);
    builder.AddFilter("System", LogLevel.Warning);
    builder.AddFilter("Program", LogLevel.Warning);
    builder.AddConsole();
    builder.AddEventLog();
});

我试图通过在服务的构造函数中使用接口 Microsoft.Extensions.Logging.ILogger 来注入服务,但出现以下错误:

I am trying to inject the service by using the Interface Microsoft.Extensions.Logging.ILogger in the constructor of the services, but I am getting the following error:

未处理的异常:System.InvalidOperationException:在尝试激活MyService"时无法解析Microsoft.Extensions.Logging.ILogger"类型的服务.

Unhandled Exception: System.InvalidOperationException: Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'MyService'.

    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
    at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateEnumerable(Type serviceType, CallSiteChain callSiteChain)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
    at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(Type serviceType)
    at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
    at Program.Main(String[] args) in Program.cs:line 27

我在这里误解了什么吗?AddLogging 方法不应该足以在 DI 容器中公开 Service 吗?

Did I misunderstand something here? Shouldn't the AddLogging method be enough to expose the Service in the DI Container?

推荐答案

依赖注入系统没有注册 ILogger.相反,它注册 ILogger.如果您需要记录器的实例,则需要接受 ILogger.

The dependency injection system doesn't register ILogger. Instead it registers ILogger<T>. If you need an instance of a logger, you will need to accept ILogger<MyService>.

这背后的原因是泛型参数用于构建记录器的类别名称——这是所有记录器都需要的.对于非通用记录器,不一定有一个好的默认名称.如果你真的想要一个非通用的ILogger,你可以像这样注册一个(随意更改名称):

The reason behind this is that the generic argument is used to build the logger's category name--something which all loggers require. With a non-generic logger there's not necessarily a good default name. If you really want a non-generic ILogger, you can register one like this (change the name as you please):

services.AddSingleton(sp => sp.GetRequiredService<ILoggerFactory>().CreateLogger("DefaultLogger"));

或者,您可以在构造函数中接受 ILoggerFactory,然后即时创建自己的记录器.

Alternatively, you can accept an ILoggerFactory in your constructor and then create your own logger on the fly.

这篇关于为什么 .NET Core DI 容器不注入 ILogger?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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