You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

派生类共享ILogger<T>、手动创建及跨库传递ILogger<T>技术问询

关于Microsoft.Extensions.Logging的共享与实例化问题解答

1. 两个派生类共享ILogger,以及不依赖DI手动创建实例

派生类共享ILogger的几种方式

  • 基类继承式共享:如果两个派生类来自同一个基类,可以在基类的构造函数中注入ILogger<BaseClass>,派生类直接继承基类的日志实例。这样所有派生类都会使用基类的logger,日志中会标记基类的类型:
    public abstract class BaseService
    {
        protected readonly ILogger<BaseService> _logger;
    
        public BaseService(ILogger<BaseService> logger)
        {
            _logger = logger;
        }
    }
    
    public class DerivedService1 : BaseService
    {
        public DerivedService1(ILogger<BaseService> logger) : base(logger) { }
    }
    
    public class DerivedService2 : BaseService
    {
        public DerivedService2(ILogger<BaseService> logger) : base(logger) { }
    }
    
  • 手动传入共享实例:如果不想用基类的logger类型,也可以手动把同一个ILogger实例传给两个派生类的构造函数。比如先创建一个共用的logger(比如ILogger<SharedLoggingMarker>,用一个空的标记类作为泛型参数),再分别传给派生类。
  • 共用LoggerFactory:让两个派生类使用同一个ILoggerFactory创建logger,这样它们的日志配置是一致的,虽然是不同的实例,但日志行为统一。

不依赖DI手动创建ILogger实例

你可以直接实例化LoggerFactory,然后用它创建指定类型的logger,完全不需要依赖注入容器:

// 1. 创建LoggerFactory并配置日志提供者
var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddConsole(); // 添加控制台输出
    builder.AddDebug(); // 添加调试窗口输出
    builder.SetMinimumLevel(LogLevel.Trace); // 设置最小日志级别
    // 还可以添加其他提供者,比如文件、EventLog等
});

// 2. 创建指定类型的ILogger实例
ILogger<DerivedService1> logger1 = loggerFactory.CreateLogger<DerivedService1>();
ILogger<DerivedService2> logger2 = loggerFactory.CreateLogger<DerivedService2>();

// 3. 传给派生类实例
var service1 = new DerivedService1(logger1);
var service2 = new DerivedService2(logger2);

如果要让两个派生类共享同一个logger实例,直接把logger1或者同一个标记类的logger传给它们即可。


2. ASP.NET Core中给.NET Standard类库传入ILogger,以及实例化依赖ILogger的类

给类库传入ILogger的正确姿势

首先,你的.NET Standard类库中的类应该通过构造函数依赖注入接收ILogger<T>,这是最符合设计原则的方式:

// .NET Standard类库中的MyClass2
public class MyClass2
{
    private readonly ILogger<MyClass2> _logger;

    // 通过构造函数接收日志实例
    public MyClass2(ILogger<MyClass2> logger)
    {
        _logger = logger;
    }

    public void Execute()
    {
        _logger.LogInformation("Executing logic in MyClass2");
    }
}

然后在ASP.NET Core控制器中,有两种方式把logger传给这个类:

方式1:直接注入ILogger并手动传入

ASP.NET Core的DI容器可以自动解析任意ILogger<T>实例,你可以直接在控制器构造函数中注入ILogger<MyClass2>,然后手动new类库实例时传入:

public class HomeController : ControllerBase
{
    private readonly ILogger<MyClass2> _class2Logger;

    public HomeController(ILogger<MyClass2> class2Logger)
    {
        _class2Logger = class2Logger;
    }

    public IActionResult Index()
    {
        // 手动创建类库实例并传入logger
        var myClass2 = new MyClass2(_class2Logger);
        myClass2.Execute();
        return Ok();
    }
}

方式2:注入ILoggerFactory,按需创建logger

如果不想提前注入所有需要的logger,也可以注入ILoggerFactory,在需要的时候再创建对应类型的logger:

public class HomeController : ControllerBase
{
    private readonly ILoggerFactory _loggerFactory;

    public HomeController(ILoggerFactory loggerFactory)
    {
        _loggerFactory = loggerFactory;
    }

    public IActionResult Index()
    {
        var class2Logger = _loggerFactory.CreateLogger<MyClass2>();
        var myClass2 = new MyClass2(class2Logger);
        myClass2.Execute();
        return Ok();
    }
}

实现"自动映射"的替代方案

C#本身没有内置的自动映射ILogger<T>到类实例的机制,但可以借助ASP.NET Core的DI容器来实现类似的效果:

把类库中的MyClass2注册到DI容器中:

// 在Program.cs中注册
builder.Services.AddTransient<MyClass2>();

然后控制器直接注入MyClass2,DI容器会自动为它创建并注入对应的ILogger<MyClass2>实例,完全不需要手动new:

public class HomeController : ControllerBase
{
    private readonly MyClass2 _myClass2;

    public HomeController(MyClass2 myClass2)
    {
        _myClass2 = myClass2;
    }

    public IActionResult Index()
    {
        _myClass2.Execute();
        return Ok();
    }
}

如果一定要手动new类实例,又不想每次都传logger,可以自己封装一个工厂类:

public class MyClass2Factory
{
    private readonly ILoggerFactory _loggerFactory;

    public MyClass2Factory(ILoggerFactory loggerFactory)
    {
        _loggerFactory = loggerFactory;
    }

    public MyClass2 Create()
    {
        return new MyClass2(_loggerFactory.CreateLogger<MyClass2>());
    }
}

把工厂注册到DI,控制器注入工厂后,就可以通过factory.Create()直接创建带logger的MyClass2实例了。


内容的提问来源于stack exchange,提问作者makerofthings7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:23:34