如何与多个类共享一个类的实例?

azi*_*ziz 5 c# logging instance

我有 ac# 网络服务。当我收到新请求时,我创建一个日志记录实例。我有许多其他类的实例来处理请求,我希望它们也记录下来。共享日志记录实例而不将其传递到构造函数或属性中的最佳方法是什么?

Jus*_*tin 5

通常,某种静态类/属性用于共享对象,而无需到处传递引用,例如:

public class Logger
{
    static Logger()
    {
        this.Instance - new Logger();
    }

    public static Logger Instance
    {
        get;
        private set;
    }

    // Other non-static members
}
Run Code Online (Sandbox Code Playgroud)

用法:

Logger.Instance.Log();
Run Code Online (Sandbox Code Playgroud)

通常,这种模式(或者至少是这种模式的变体)被称为单例模式

上面有很多变化,例如,在日志框架中,以下轻微变化比上面更常见:

public class Logger
{
    static Logger()
    {
        this.Instance = new Logger();
    }

    public static Logger Instance
    {
        get;
        private set;
    }

    public static void Log() 
    {
        Logger.Instance.Log();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

Logger.Log();
Run Code Online (Sandbox Code Playgroud)


小智 3

单例模式是一种反模式;我想不出很多应该使用或推荐它的实例,包括在这个实例中,用于日志记录。

我们如何处理日志记录:日志记录实例通过构造函数注入注入到所有需要它的类中。例如:

public class MyClass
{
    private readonly ILogger _logger;

    public MyClass(ILogger logger)
    {
        _logger = logger;
    }

    public void DoStuff()
    {
        _logger.Trace("DoStuff called");
    }
}
Run Code Online (Sandbox Code Playgroud)

注入的日志记录实例可以每次都是一个新实例,或者如果您想拥有一个实例记录器,则可以创建一次并根据需要传递。

但是:我强烈推荐第一个选项,即使用 DI 来使用组合根模式构建类。我还建议使用日志框架,例如 NLog 或 log4net。这些是可配置的,并且易于与电子邮件、事件查看器、文件等一起使用,并且可以在多线程环境中工作。

我们有自己定义的ILogger,里面有Trace、Warn、Info、Exception等,然后使用NLog实现了这个接口。这意味着我们可以通过创建 ILogger 的新实现然后进行简单的 DI 配置更新来轻松更改日志记录方式。这是迄今为止对我们来说非常有效的一种日志记录解决方案。