【发布时间】:2012-07-10 23:54:19
【问题描述】:
我有一个 c# 网络服务。当我收到一个新请求时,我会创建一个日志记录实例。我有许多其他类的其他实例来处理请求,我希望它们也能记录下来。共享日志实例而不将其传递给构造函数或属性的最佳方法是什么?
【问题讨论】:
-
你使用什么日志框架?
-
下面的答案很好(基本上使用静态实例,由单例保护)。但是,请考虑使用 DI 容器来管理它。让每个人的生活更轻松。
我有一个 c# 网络服务。当我收到一个新请求时,我会创建一个日志记录实例。我有许多其他类的其他实例来处理请求,我希望它们也能记录下来。共享日志实例而不将其传递给构造函数或属性的最佳方法是什么?
【问题讨论】:
通常使用某种静态类/属性来共享对象,而无需到处传递引用,例如:
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();
【讨论】:
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 配置更新来轻松更改我们的日志记录方式。这是迄今为止对我们非常有效的一种日志记录解决方案。
【讨论】:
单例模式。
即具有私有构造函数的类。您使用公共静态方法只创建一个类的实例并返回该对象。
编辑:还值得注意的是,您需要将此类放在自己的项目中,以便所有类都可以引用它。
【讨论】:
好吧,您可以让您的日志记录类包含静态方法,这些方法实际写入内存/刷新到磁盘。您也可以查看Singleton Pattern
【讨论】:
您可以使用Singleton Pattern 确保整个系统中只有一个日志记录对象实例。
将日志记录对象传递给构造函数或作为属性实际上会使您的代码更容易测试,具体取决于您实现单例模式的方式。日志记录是令人讨厌的横切关注点之一,总是需要权衡取舍。
【讨论】:
通常在每个类中创建一个新的记录器实例不是问题。 Log4Net 记录器构造函数将类型作为参数,以便为您提供更好的日志。
【讨论】:
使用静态字段(我假设 C# 支持这些)。语法应该是这样的:
private static final Logger logger = new Logger(...);
只要你需要在课堂上记录一些东西,就可以使用它。
【讨论】: