我有一个c#web服务。当我得到一个新的请求时,我创建一个日志记录实例。我有很多其他类的实例来处理请求,我也希望它们能够记录。共享日志记录实例而不将其传递给构造函数或属性的最佳方式是什么?如何与多个类共享一个类的实例?
回答
Singleton Pattern is an anti-pattern;我无法想象应该使用或推荐使用或推荐的很多情况,包括在这种情况下,用于日志记录。
我们如何处理日志记录:通过构造器注入将日志记录实例注入到所有需要它的类中。例如:
public class MyClass
{
private readonly ILogger _logger;
public MyClass(ILogger logger)
{
_logger = logger;
}
public void DoStuff()
{
_logger.Trace("DoStuff called");
}
}
测井例如注射,每次可以是一个新的实例,或者如果你是在具有可创建一次,并通过根据需要在单个实例记录器弯曲。
但是,我强烈建议第一个选项,使用DI来构建您的类使用Composition Root模式。我还建议使用日志框架,例如NLog或log4net。这些可配置并易于使用的电子邮件,事件查看器,文件等。和在多线程环境中工作。
我们有自己定义的ILogger,它有Trace,Warn,Info,Exception等等,然后用NLog实现这个接口。这意味着我们可以通过创建ILogger的新实现并进行简单的DI配置更新来轻松更改我们的日志记录。这是迄今为止我们工作得很好的一种日志记录解决方案。
这是一种劣质的方法 - 尤其是如果你有几个类似的要求,你的构造者看起来很荒谬。它远远优于让你的班级具有智慧并且能够自主决定他们的环境。整个DI理论是业余的,马虎的。静态类没有什么问题,如果你正在编写c#,那么当你引用任何MS核心程序集时,你已经完全绑定了它们。 String.Format() - 等...不妨使用Logging.Log() – hajikelist 2015-05-11 16:27:11
那么,你可以让你的日志记录类包含静态方法,这些方法将实际写入内存/刷新到磁盘。你也可以看看Singleton Pattern
使用一个静态字段(我假设C#支持这些)。语法应该与此类似:
private static final Logger logger = new Logger(...);
并且只要您需要在课程中记录某些内容时使用它。
我认为你的意思是只读而不是最后? – 2010-10-22 00:00:21
我是Java开发人员。这对我们来说是'最后的'。 ;-)。是的,那是我的最终答案.... – 2010-10-22 00:23:49
您可以使用Singleton Pattern确保整个系统中只有一个记录对象实例。
将日志对象传递给构造函数或属性实际上会使您的代码更易于测试,具体取决于您如何实现Singleton模式。日志记录是那些令人烦恼的交叉问题之一,总是有权衡。
通常在每个班级中创建记录器的新实例并不是问题。 Log4Net记录器构造函数采用一种类型作为参数,为您提供更好的日志。
通常某种静态类/属性的用于共享的对象,而无需到处通过引用,例如:
public class Logger
{
static Logger()
{
this.Instance - new Logger();
}
public static Logger Instance
{
get;
private set;
}
// Other non-static members
}
用法:
Logger.Instance.Log();
通常这种(或至少在此变化)被称为singleton pattern。
上有上述许多变化,例如下列细微变化是比在日志框架上述多见:
public class Logger
{
static Logger()
{
this.Instance = new Logger();
}
public static Logger Instance
{
get;
private set;
}
public static void Log()
{
Logger.Instance.Log();
}
}
用法:
Logger.Log();
这是一个最佳解决方案;把Logger放在自己的库中,这样你就可以从其他项目中引用它。 – 2010-10-22 00:38:21
Singleton模式。
也就是说,一个具有私有构造函数的类。您使用公共静态方法仅创建该类的一个实例并返回该对象。
编辑:另外值得注意的是,您需要将此类放在其自己的项目中,以便它可以被所有类引用。
- 1. C#让多个类共享另一个类的相同实例
- 2. 几个类共享另一个类的实例
- 3. 如何在多个服务器实例上共享类定义?
- 4. ASMX服务共享单个类实例
- 5. 跨多个类实例共享变量,我可以在类
- 6. 共享一个PrintDocument实例
- 7. 如何在一个类的不同实例之间共享一个互斥量?
- 8. 如何:多个Django实例共享一个全局变量?
- 9. 在C#中的多个对象之间共享一个实例化的类
- 10. 如何在C#中的一个类的多个实例之间共享一个值?
- 11. 是否有多个类实例共享此列表?
- 12. 如何与多个html文件共享javascript websocket实例
- 13. 模板类的实例之间是否共享一个范围?
- 14. 共享变量的多个ScriptControl实例
- 15. PHP - 如何跨多个子类共享设置并实例化这些共享设置一次?
- 16. 与另一个控件共享属性的一个实例?
- 17. 如何使用类方法分发UIManagedDocument的多个共享实例?
- 18. 一个片段类的多个实例
- 19. 一个类的多个实例
- 20. 在活动之间共享一个类实例
- 21. 的iOS:保留一个共享实例
- 22. 如何在多个操作中共享一个对象的单个实例?
- 23. 在多个类之间共享一个类
- 24. 在一个类的所有实例之间共享一个变量
- 25. 设置多对多表共享一个共同的类型
- 26. Dos同一个MovieClip的多个实例共享Cache吗?
- 27. 如何让多个类共享指向普通类的指针
- 28. 如何实现一个具有多个独立公共接口的案例类?
- 29. 如何与多个目标c类共享xib文件
- 30. 如何让一个类的实例成为Jena中另一个类的实例?
你正在使用什么日志框架? – 2010-10-21 23:59:07
下面的答案很好(基本上使用一个静态实例,由单身守卫)。不过,可以考虑使用DI容器来管理它。使每个人的生活更轻松。 – RPM1984 2010-10-22 00:06:47