如何在不使用依赖注入的情况下在类库中使用ILogger<Class>
解决方案
1. 类库安装依赖包
仅需安装NuGet包 Microsoft.Extensions.Logging.Abstractions,这个包仅包含日志抽象定义,无任何依赖注入相关的强制依赖。
2. 类库中实现静态日志入口
在类库中新增静态日志提供类,用于外部配置日志工厂,同时提供默认空日志实现避免未配置时报错:
using Microsoft.Extensions.Logging; namespace Binance.WebSocket.Client; public static class LogProvider { private static ILoggerFactory _loggerFactory = NullLoggerFactory.Instance; /// <summary> /// 供外部调用配置日志工厂 /// </summary> /// <param name="loggerFactory"></param> /// <exception cref="ArgumentNullException"></exception> public static void SetLoggerFactory(ILoggerFactory loggerFactory) { _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); } /// <summary> /// 创建指定类别的日志实例 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static ILogger<T> CreateLogger<T>() => _loggerFactory.CreateLogger<T>(); /// <summary> /// 创建指定名称的日志实例 /// </summary> /// <param name="categoryName"></param> /// <returns></returns> public static ILogger CreateLogger(string categoryName) => _loggerFactory.CreateLogger(categoryName); }
3. 类库内部使用日志
类库中的类可同时兼容DI和非DI场景获取日志实例:
namespace Binance.WebSocket.Client; public class BinanceWebSocketCommunicator { private readonly ILogger<BinanceWebSocketCommunicator> _logger; // 支持DI注入ILogger的场景 public BinanceWebSocketCommunicator(Uri uri, ILogger<BinanceWebSocketCommunicator> logger) { _logger = logger; // 其他初始化逻辑 } // 支持无DI直接构造的场景,从静态入口获取日志实例 public BinanceWebSocketCommunicator(Uri uri) : this(uri, LogProvider.CreateLogger<BinanceWebSocketCommunicator>()) { } // 内部业务代码使用日志示例 public void SomeInternalMethod() { _logger.LogDebug("执行内部方法,参数:{Param}", "test"); } }
4. 示例应用对接Serilog
在现有Serilog示例项目中安装NuGet包 Serilog.Extensions.Logging,修改Main方法,在配置完Serilog后将其注册到类库的日志入口即可:
Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .Enrich.FromLogContext() .WriteTo.Console(LogEventLevel.Debug, theme: SystemConsoleTheme.Colored) .WriteTo.File(Path.Combine("logs", "verbose.log"), rollingInterval: RollingInterval.Day) .CreateLogger(); // 新增这行,将Serilog实现注入类库 LogProvider.SetLoggerFactory(new SerilogLoggerFactory(Log.Logger));
完成以上配置后,类库内部输出的所有日志都会自动通过你配置的Serilog输出到控制台、文件等目标,全程不需要引入依赖注入框架。
该方案的优势:
- 完全遵循Microsoft.Extensions.Logging标准规范,后续切换日志框架(如NLog、Log4Net)不需要修改类库代码
- 同时支持DI和非DI两种使用场景,兼容不同用户的使用习惯
- 未配置日志时默认使用空日志实现,不会抛出异常,也无多余性能开销
- 无多余依赖,类库仅依赖轻量的抽象包
内容的提问来源于stack exchange,提问作者nop
相关产品推荐
相关产品推荐

