如何在具有单例模式的 .NET 库中使用 ILogger 抽象?
How can I use ILogger abstractions in a .NET Library with a singleton pattern?
我有一个 class 库,目前使用 NLog 进行日志记录。我想更新此库以使用 Microsoft.Extensions.Logging.Abstractions 的 ILogger<T>
抽象,以便此库的使用者可以选择自己的日志记录框架。
该库使用带有私有构造函数和 Instance 属性:
的单例模式
public static MyLibrary Instance { get; } = new MyLibrary();
private MyLibrary()
{
...
}
有什么建议可以让这个库保持单例,同时允许消费者在 startup/object 创建时提供 ILogger
实现?有没有办法让这个库在不改变单例模式的情况下接受来自其他应用程序的日志记录实现?
您可以为记录器添加一个全局 属性,大概类似于
public static ILoggerFactory LoggerFactory {get;set;} = NullLoggerFactory.Instance;
全局状态的所有潜在问题都适用,即使大多数日志记录框架可能是线程安全的。
一个明显的缺点是,除非消费者实际设置 loggerFactory,否则不会发生日志记录。您还需要考虑初始化顺序。最明显的解决方案是停止使用单例,而是使用采用 loggerFactory 的工厂方法。即
public static MyLibrary CreateMyLibrary(ILoggerFactory factory)
如果消费者想将创建的库放在全局字段中,他可以随意这样做。
我有一个 class 库,目前使用 NLog 进行日志记录。我想更新此库以使用 Microsoft.Extensions.Logging.Abstractions 的 ILogger<T>
抽象,以便此库的使用者可以选择自己的日志记录框架。
该库使用带有私有构造函数和 Instance 属性:
的单例模式public static MyLibrary Instance { get; } = new MyLibrary();
private MyLibrary()
{
...
}
有什么建议可以让这个库保持单例,同时允许消费者在 startup/object 创建时提供 ILogger
实现?有没有办法让这个库在不改变单例模式的情况下接受来自其他应用程序的日志记录实现?
您可以为记录器添加一个全局 属性,大概类似于
public static ILoggerFactory LoggerFactory {get;set;} = NullLoggerFactory.Instance;
全局状态的所有潜在问题都适用,即使大多数日志记录框架可能是线程安全的。
一个明显的缺点是,除非消费者实际设置 loggerFactory,否则不会发生日志记录。您还需要考虑初始化顺序。最明显的解决方案是停止使用单例,而是使用采用 loggerFactory 的工厂方法。即
public static MyLibrary CreateMyLibrary(ILoggerFactory factory)
如果消费者想将创建的库放在全局字段中,他可以随意这样做。