【问题标题】:How to make Log4Net wrapper class as a singleton class?如何将 Log4Net 包装类作为单例类?
【发布时间】:2013-03-06 12:58:47
【问题描述】:

我有一个 log4net 包装类...但是每次从其他类调用它以记录错误时,我都需要实例化它。我需要克服这个问题。最近我遇到了我不熟悉的单例类。因此我需要帮助将我当前的包装类转换为单例类。

我正在发布我目前在下面使用的 log4net 包装类..

using System;
using System.Data;
using System.Configuration;
using Asset.Business;

/// <summary>
/// Summary description for Logger
/// </summary>

namespace AssetsDataService
{
    public class ErrorLogger
    {
        private static log4net.ILog logger = null;
        public ErrorLogger()
        {
            if (logger == null)
            {

                string logConfigPath = ConfigSettings.GetEnvConfigValue("LogConfigXMLPath"); // this contains the path of the xml

                System.IO.FileInfo fileInfo = new System.IO.FileInfo(logConfigPath);
                log4net.Config.DOMConfigurator.Configure(fileInfo);

                string loggerName = ConfigurationManager.AppSettings.Get("ErrorLoggerName"); // this contains the name of the logger class

                logger = log4net.LogManager.GetLogger(loggerName);
            }

        }

        public void Fatal(Object message)
        {
            logger.Fatal(message);
        }

        public void Fatal(Object message, Exception exception)
        {
            logger.Fatal(message, exception);
        }

        public void Error(Object message)
        {
            logger.Error(message);
        }

        public void Error(Object message, Exception exception)
        {
            logger.Error(message, exception);

        }

        public void Debug(Object message)
        {

            logger.Debug(message);
        }

        public void Info(Object message)
        {
            logger.Info(message);
        }
    }
}

这是我试图使我的包装类单例的代码:

using System;
using System.Data;
using System.Configuration;
using Asset.Business;

/// <summary>
/// Summary description for Logger
/// </summary>

namespace AssetsDataService
{
    public class ErrorLogger
    {

        private static volatile ErrorLogger instance;
        private static object syncRoot = new Object();
         private static log4net.ILog logger = null;

        private ErrorLogger()
        {
            if (logger == null)
            {

                string logConfigPath = ConfigSettings.GetEnvConfigValue("LogConfigXMLPath"); // this contains the path of the xml

                System.IO.FileInfo fileInfo = new System.IO.FileInfo(logConfigPath);
                log4net.Config.DOMConfigurator.Configure(fileInfo);

                string loggerName = ConfigurationManager.AppSettings.Get("ErrorLoggerName"); // this contains the name of the logger class

                logger = log4net.LogManager.GetLogger(loggerName);
            }

        }

        public static ErrorLogger Instance()
        {

            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new ErrorLogger();
                }
            }

            return instance;
         }


        public void Fatal(Object message)
        {
            logger.Fatal(message);
        }

        public void Fatal(Object message, Exception exception)
        {
            logger.Fatal(message, exception);
        }

        public void Error(Object message)
        {
            logger.Error(message);
        }

        public void Error(Object message, Exception exception)
        {
            logger.Error(message, exception);

        }

        public void Debug(Object message)
        {

            logger.Debug(message);
        }

        public void Info(Object message)
        {
            logger.Info(message);
        }
    }
}

这个类是正确的单例类吗?它会正确处理日志吗?

我将如何调用记录器 ErrorLogger 类来记录错误或信息等。

通过使用我以前的普通类,我将其称为

ErrorLogger log = new ErrorLogger();
log.Error(string.Concat("Exception Occurred :" + ex.Message, "/n", ex.StackTrace));

如果我使用单例类,如何登录??

【问题讨论】:

  • 一般来说我会考虑实施 IoC/DI。 Unity、Ninject、Autofac 非常流行,您应该能够找到大量关于如何使用这些的信息
  • @Ramunas ya 我已经读过...我的疑问是,如果我将其设置为单例类,我将如何在其他类中调用记录器类
  • 如果 Logger 是单例的,那么它将是 ErrorLogger.Instance.Debug("test")
  • @Ramunas 我已经编辑了我的问题.. 请检查编辑并建议我这样做..

标签: c# multithreading singleton log4net


【解决方案1】:

这是单例模式的正确实现。您可以使用以下语句调用方法进行日志记录:

ErrorLogger.Instance.Fatal(Exception);

请注意,此实现不是线程安全的,这意味着如果您使用多个线程使用此记录器记录不同的消息,您可能会遇到一些意外的异常。您可以通过用锁包围所有公共方法来快速而肮脏地解决此问题。

例如:

private object _lock = new object();

public void Error(Object message)
{
    lock(_lock){
        logger.Error(message);
    }
}

还要确保在类中的每个公共方法上使用相同的锁定对象。

【讨论】:

  • 谢谢你的澄清..:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-26
相关资源
最近更新 更多