如何在单例类中使用瞬态记录器,Simple Injector

时间:2016-04-27 12:54:58

标签: c# logging dependency-injection log4net simple-injector

我有一个LogManager类,它有一个类型参数,可以像这样提供给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);

它的工作原理应该如此,我将日志管理器注入我的控制器的构造并使用它。但有一个问题。我有很多单例类也应该使用日志管理器,但我不能将它注入它们,因为日志管理器的寿命比其他人短,因此Simple Injector不允许我这样做。

建议的解决方案是将日志工厂类注入其他单例并每次调用工厂,这听起来像个坏主意。每次我想记录某事时,我都不想做 _logFactory.GetLogger()。Debug(“log”)。或者我错过了关于这个解决方案的一些内容?

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

有任何建议我该怎么办?我的设计有什么问题吗?

1 个答案:

答案 0 :(得分:3)

你应该注册单身:

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>单例没问题。