首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对于库,我应该使用ILogger、ILogger<T>、ILoggerFactory还是ILoggerProvider?

对于库,我应该使用ILogger、ILogger<T>、ILoggerFactory还是ILoggerProvider?
EN

Stack Overflow用户
提问于 2018-07-15 12:08:08
回答 7查看 48.9K关注 0票数 154

这可能在某种程度上与将ILogger或ILoggerFactory传递给AspNet核心中的构造函数?,然而,这是专门关于库设计,而不是关于使用这些库的实际应用程序如何实现其日志记录。

我正在编写一个.net标准2.0库,它将通过Nuget安装,并允许使用该库的人获得一些调试信息,我依赖于Microsoft.Extensions.Logging.Abstractions允许注入一个标准化的记录器。

然而,我看到了多个界面,web上的示例代码有时会使用ILoggerFactory并在类的ctor中创建记录器。还有ILoggerProvider它看起来像工厂的只读版本,但实现可能实现也可能不实现这两个接口,所以我不得不选择。(工厂似乎比提供者更常见)。

我见过的一些代码使用了非泛型ILogger接口,甚至可能共享同一记录器的一个实例,有些还会使用ILogger在它们的ctor中,并期望DI容器支持开放泛型类型或显式注册每个ILogger我的库使用的变体。

现在,我确实认为ILogger是正确的方法,并且可能是一个不接受该参数的ctor,而只是传递一个Null Logger。这样,如果不需要日志记录,就不会使用日志。然而,一些DI容器选择了最大的ctor,因此无论如何都会失败。

我很好奇我是什么

假设在这里这样做是为了给用户带来最少的麻烦,同时如果需要的话,仍然允许适当的日志支持。

EN

Stack Overflow用户

回答已采纳

发布于 2018-07-18 14:09:12

定义

我们有3个接口:ILogger, ILoggerProvider和ILoggerFactory..。让我们看一下源代码要找出他们的职责:

ILogger:负责写入给定的日志消息日志级别..。

ILoggerProvider:负责创建ILogger(您不应该使用ILoggerProvider直接创建记录器)

ILoggerFactory:您可以注册一个或多个ILoggerProviderS与工厂一起使用,而工厂又使用所有它们来创建ILogger. ILoggerFactory..。包含一个集合,该集合包含ILoggerProviders..。

在下面的示例中,我们向工厂注册了2个提供程序(控制台和文件)。当我们创建记录器时,工厂使用这两个提供程序来创建

代码语言:javascript
运行
复制
ILoggerFactory factory = new LoggerFactory().AddConsole();    // add console provider
factory.AddProvider(new LoggerFileProvider("c:\\log.txt"));   // add file provider
Logger logger = factory.CreateLogger(); // <-- creates a console logger and a file logger

因此记录器本身维护着一个集合ILoggers,并将日志消息写入所有这些日志。查看记录器源代码

我们可以确认Logger具有一个数组,该数组包含(即LoggerInformation[]),同时它正在实现ILogger

接口。

依赖注入

MS文档提供两种注入记录器的方法:

1.注入工厂:

公共TodoController(ITodoRepository todoRepository、ILoggerFactory记录器){_todoRepository = todoRepository;_记录器= logger.CreateLogger("TodoApi.Controllers.TodoController");}

创建类别为TodoApi.Controllers.TodoController的记录器..。

2.注入泛型ILogger

公共TodoController(ITodoRepository todoRepository、ILogger记录器){_todoRepository = todoRepository;_logger = logger;}

创建一个记录器,其Category = fully qualified type name为TodoController

在我看来,文档之所以令人困惑,是因为它没有提到任何关于注入非泛型的内容,ILogger..。在上面的示例中,我们注入了一个非泛型ITodoRepository然而,这并不能解释为什么我们没有对..。ILogger

根据马克·塞曼

注入构造器应该只接收依赖项。

将工厂注入到Controller中不是一个好方法,因为初始化Logger不是Controller的责任(违反SRP)。同时将泛型ILogger添加不必要的噪波。请参见

简单的注入器有关更多详细信息,请访问博客:ASP.NET核心DI抽象出了什么问题?

应该注入的(至少根据上面的文章)是一个非泛型ILogger,但是,这不是微软内置的DI Container可以做的事情,您需要使用第三方DI库。这些两个文档解释了如何将第三方库与.NET核心一起使用。这是另一篇文章

由Nikola Malovic撰写,他在书中解释了他的IoC五定律。

尼古拉第四IoC定律

要解析的类的每个构造函数除了接受一组自己的依赖项外,不应该有任何实现。

票数 169
EN
查看全部 7 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51345161

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档