.NET Core托管模式下复用HostBuilder LoggerFactory创建类库Logger实例
嘿,这个问题我之前在做.NET Core后台服务的时候也遇到过,其实有两种很实用的解决办法,咱们来聊聊:
解决方法
方法一:直接注入ILoggerFactory到HostedService
既然你的HostBuilder已经配置好了完整的日志系统,那最简单的方式就是把ILoggerFactory直接注入到SkillsService的构造函数里,然后用它来创建自定义类库中对应的Logger实例。
修改你的SkillsService代码:
public class SkillsService : IHostedService, IDisposable { private readonly ILogger<SkillsService> _logger; private readonly ILoggerFactory _loggerFactory; // 在构造函数中注入ILoggerFactory public SkillsService(ILogger<SkillsService> logger, ILoggerFactory loggerFactory) { _logger = logger; _loggerFactory = loggerFactory; } public async Task StartAsync(CancellationToken cancellationToken) { // 方式1:用完整命名空间创建Logger var customClassLogger = _loggerFactory.CreateLogger("CustomLibrary.YourTargetClass"); // 方式2:如果能拿到类的Type,用泛型更安全 // var customClassLogger = _loggerFactory.CreateLogger<CustomLibrary.YourTargetClass>(); // 实例化自定义类并传入Logger var customInstance = new CustomLibrary.YourTargetClass(customClassLogger); // 接下来就可以正常使用这个实例了 customInstance.DoYourWork(); } // 其他原有方法保持不变 public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; public void Dispose() { } }
这种方式的好处是不需要改动太多现有代码,直接复用已配置的日志工厂。
方法二:将自定义类注册到依赖注入容器(更推荐)
如果你的自定义类本身适合用依赖注入管理,那更推荐把它注册到Host的DI容器里,这样DI系统会自动帮你注入符合配置的Logger,完全不需要手动创建实例。
步骤1:确保自定义类接受ILogger注入
首先修改你自定义类库中的目标类,让它的构造函数接收ILogger<YourTargetClass>:
namespace CustomLibrary { public class YourTargetClass { private readonly ILogger<YourTargetClass> _logger; public YourTargetClass(ILogger<YourTargetClass> logger) { _logger = logger; } public void DoYourWork() { _logger.LogInformation("自定义类开始工作啦"); // 你的业务逻辑 } } }
步骤2:在HostBuilder中注册自定义类
回到你的主机构建代码,在ConfigureServices里添加自定义类的注册(根据你的业务需求选择生命周期:Singleton/Scoped/Transient):
public static async Task Main(string[] args) { var builder = new HostBuilder() .ConfigureAppConfiguration((hostingContext, config) => { ... }) .ConfigureServices((hostContext, services) => { services.AddSingleton<IHostedService, SkillsService>(); // 注册自定义类,这里用Transient举例,你可以根据实际情况调整 services.AddTransient<CustomLibrary.YourTargetClass>(); }) .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); }); await builder.RunConsoleAsync(); }
步骤3:在SkillsService中注入自定义类
最后修改SkillsService,直接注入自定义类的实例:
public class SkillsService : IHostedService, IDisposable { private readonly ILogger<SkillsService> _logger; private readonly CustomLibrary.YourTargetClass _customInstance; // 直接注入自定义类,DI会自动给它配置好Logger public SkillsService(ILogger<SkillsService> logger, CustomLibrary.YourTargetClass customInstance) { _logger = logger; _customInstance = customInstance; } public async Task StartAsync(CancellationToken cancellationToken) { // 直接使用即可,Logger已经配置完成 _customInstance.DoYourWork(); } // 其他原有方法保持不变 public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; public void Dispose() { } }
这种方式更符合.NET Core依赖注入的设计理念,不仅能自动处理日志注入,还能让你后续更方便地扩展自定义类的依赖,同时也更易于单元测试。
内容的提问来源于stack exchange,提问作者Jiří Kubeš
相关产品推荐
相关产品推荐

