如何在单例 类 中使用瞬态记录器,简单注入器

How to use transient logger in singleton classes, Simple Injector

我有一个 LogManager class,它有一个像这样给 log4net 的类型参数:

public class LogManager<T> : ILogManager
{
    private ILog Logger { get; set; }

    public LogManager()
    {
        Logger = LogManager.GetLogger(typeof(T));
    }
}

并且我将此记录器注册为有条件的:

container.RegisterConditional(typeof(ILogManager),
c => typeof(LogManager<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Transient,
c => true);

它像预期的那样工作,我将日志管理器注入到我的控制器的构造函数中并使用它。但有一个问题。我有很多单例 classes 也应该使用日志管理器,但我不能将其注入它们,因为日志管理器的寿命比其他管理器短,所以 Simple Injector 不允许我这样做.

建议的解决方案是向其他单例注入一个日志工厂 class 并每次调用该工厂,这听起来是个坏主意。我不想 _logFactory.GetLogger().Debug("log") 每次我想记录一些东西。或者我遗漏了有关此解决方案的某些信息?

另一个提议的解决方案是使单例 classes 瞬态,这没有任何意义。

有什么建议我应该如何进行?我的设计有什么问题吗?

你应该注册单例:

container.RegisterConditional(typeof(ILogManager),
    c => typeof(LogManager<>).MakeGenericType(c.Consumer.ImplementationType),
    Lifestyle.Singleton,
    c => true);

由于LogManager<> 是泛型类型,Simple Injector 将为每个封闭的泛型版本创建一个实例。所以 LogManager<HomeController>LogManager<UsersController> 是不同的实例。这仅仅是因为没有办法使用相同的实例(这在 .NET 中是不可能的)。所以每个消费者仍然会有自己的 LogManager<T> 和自己的 log4net ILog 实现。从 log4net 的 LogManager.GetLogger 返回的记录器是线程安全的,这就是为什么创建您自己的 LogManager<T> 单例没有问题的原因。