问题
I have a log4net wrapper class... But i need to instantiate everytime when i call it from other classes to log the error. I need to overcome that.. Recently i came across the singleton class which is not familiar to me.. Hence I need help in converting my current wrapper class to the singleton class..
I am posting my log4net wrapper class which i am currently using below..
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);
}
}
}
And this is the code which i tried to make my wrapper class singleton:
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);
}
}
}
Is this class a correct singleton class and will it handle logging correctly?
How would i call the logger ErrorLogger class to log an error or info etc..
By using my normal class i used to call it as
ErrorLogger log = new ErrorLogger();
log.Error(string.Concat("Exception Occurred :" + ex.Message, "/n", ex.StackTrace));
How can i log if i use the singleton class??
回答1:
This is a correct implementation of the singleton pattern. You can call the methods to log with the following statement:
ErrorLogger.Instance.Fatal(Exception);
Please notice that this implementation isn't thread safe, this means if you use several threads to log different messages with this logger you might get some unexpected exceptions. You can fix this quick and dirty by surrounding all your public methods with a lock.
For example:
private object _lock = new object();
public void Error(Object message)
{
lock(_lock){
logger.Error(message);
}
}
also make sure you use the same lock object on every public method inside the class.
来源:https://stackoverflow.com/questions/15247988/how-to-make-log4net-wrapper-class-as-a-singleton-class