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

查看:127
本文介绍了为什么.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容器中公开服务?

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

推荐答案

依赖项注入系统未注册ILogger.相反,它注册ILogger<T>.如果需要记录器的实例,则需要接受ILogger<MyService>.

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天全站免登陆