C# 两个派生类如何共享Microsoft.Extensions.Logging.ILogger<;T>;日志框架?

C# 两个派生类如何共享Microsoft.Extensions.Logging.ILogger<;T>;日志框架?,c#,asp.net-core,asp.net-core-mvc,C#,Asp.net Core,Asp.net Core Mvc,在ASP.NET Core中,默认解析器将解析控制器中的Microsoft.Extensions.Logging.ILogger 假设我创建了一个从控制器调用的新的.NET标准库 如何将Microsoft.Extensions.Logging实例传递到其中 如果需要ILogger,如何创建类的new()实例 C#是否可以手动自动映射ILogger,并将其传递到我的库中 您应该为此使用依赖项注入 您的控制器通过引用其构造函数中的接口来利用DI资源。对于ILogger这看起来像: public c

在ASP.NET Core中,默认解析器将解析控制器中的Microsoft.Extensions.Logging.ILogger

假设我创建了一个从控制器调用的新的.NET标准库

如何将
Microsoft.Extensions.Logging
实例传递到其中

  • 如果需要
    ILogger
    ,如何创建类的
    new()
    实例
  • C#是否可以手动自动映射
    ILogger
    ,并将其传递到我的库中
您应该为此使用依赖项注入

您的
控制器
通过引用其构造函数中的接口来利用DI资源。对于
ILogger
这看起来像:

public class MyAwesomeController : Controller
{
    private readonly ILogger _logger;

    public MyAwesomeController(ILogger<MyAwesomeController> logger)
    {
        // logger contains a refference to the DIed ILogger 
        // We assign it to _logger so we can reference it from other
        // methods in the class
        _logger = logger;
    }

    public IActionResult GetIndex()
    {
        // Log something
        //_logger.LogInformation();
        return View();
    }
}
公共类MyAwesomeController:Controller
{
专用只读ILogger\u记录器;
公共MyAwesomeController(ILogger记录器)
{
//记录器包含对ILogger的引用
//我们将其分配给_logger,以便从其他日志中引用它
//课堂上的方法
_记录器=记录器;
}
public IActionResult GetIndex()
{
//记录某事
//_logger.LogInformation();
返回视图();
}
}

您可以在文档中找到更多详细信息:

有时依赖项注入不可用,或者当您处于不应该使用DI的环境中时(例如单元测试,您要显式定义每个注入的服务),与某些形式的集成测试一样

在这些情况下-如果您不关心日志记录(例如在原型设计或实验时),请使用
NullLogger
,它内置于
Microsoft.Extensions.logging.Abstractions
(这是所有使用MEL的项目都必须引用的通用NuGet包,因此保证可用)

例如,如果您的服务实现需要一个非空的
ILogger

如果您确实关心所记录的内容,那么不幸的是,您确实需要实现自己的
ILogger工厂
(并记录到一些内部缓冲区),但您不需要提供自己的
CreateLogger()
方法来创建强类型的
ILogger
实例,在MEL库中作为扩展方法免费提供

关于子类 你在文章中提到“派生”类-因为如果你有这个

public class BaseService
{
    public BaseService( ILogger<BaseService> log )
    {
        // ...
    }
}

public class DerivedService : BaseService
{
    // ...?
}
您可以使用
NullLogger
实例化
DerivedService
BaseService
的实例,如我前面的示例所示:

BaseService bs = new BaseService( NullLoggerFactory.Instance.CreateLogger<BaseService>() );

DerivedService ds = new DerivedService ( NullLoggerFactory.Instance.CreateLogger<DerivedService>() );
C#的类型推断规则将确保您不需要提供显式的
TService
泛型参数类型参数,如下所示:

TurboEncabulatorService service = CreateServiceWithNullLogger( log => new TurboEncabulatorService( log ) );

使用
new
超越了首先使用依赖注入框架的目的。在任何情况下,
Logger
(形成Logger包)只是
ILoggerFactory
的包装类,请参见。但是,如果您想在库中使用
ILogger
,强烈建议您一直使用依赖项注入,因为您不必担心代码中的具体类型和实例化,DI/应用程序会这样做,并且可以用任何其他实现(即库升级或替换)来替换它@Tseng我如何一直使用DI?我知道如何使用DI,但不使用DII调用类您不需要调用库中的任何具体类。只需使用接口(通过注入构造函数)。其他一切都在应用程序中配置(即在ASP.NET Core应用程序中,通过配置记录器,或在主应用程序中手动执行,即通过调用
iSeries上的
.AddLogging
方法)。或者手动注册它,但这是不可取的,因为它可能会在将来的版本中更改,并且您需要更新您的代码
public class BaseService
{
    public BaseService( ILogger<BaseService> log )
    {
        // ...
    }
}

public class DerivedService : BaseService
{
    public DerivedService( ILogger<DerivedService> log )
        : base( log ) // `ILogger<BaseService>` can accept an `ILogger<DerivedService>`!
    {
    }
}
BaseService bs = new BaseService( NullLoggerFactory.Instance.CreateLogger<BaseService>() );

DerivedService ds = new DerivedService ( NullLoggerFactory.Instance.CreateLogger<DerivedService>() );
public static TService CreateServiceWithLogger<TService>( Func<ILogger<TService>,TService> ctor )
{
    ILogger<TService> log = NullLoggerFactory.Instance.CreateLogger<TService>();
    return ctor( log );
}
TurboEncabulatorService service = CreateServiceWithNullLogger( log => new TurboEncabulatorService( log ) );