C# Logging design: Extension method, alternatives?

和自甴很熟 提交于 2020-01-02 17:44:13

问题


I'd like to write a logger that can be easily appended to any class in my current project. For development, it will be convenient to log messages to the console, whereas in the final release I'd like to log to a file or something. One should be able to change the behavior by editing just a few lines of code, or ideally a settings file.

What I have so far is this class structure:

public interface ILogger {
    void LogMessage(String message);
    // ... other logging functions (exceptions, time etc.) don't matter here
};

public interface ILoggable { };

public static class LoggingProvider {
    private static ILogger logger = ConsoleLogger.handle;
        public static void LogMessage(this ILoggable obj, String message) {
        logger.LogMessage(message);
    }
}


public sealed class NullLogger : ILogger {
        // A logger that does nothing..
};

public sealed class FileLogger : ILogger {
    // A logger that writes to a file..
};

public sealed class ConsoleLogger : ILogger {
    #region Console Allocation
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool AllocConsole();
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool FreeConsole();
    #endregion

    #region Singleton implementation
    private static Object cs = new Object();
    private static ILogger instance = null;
    private ConsoleLogger() {
        AllocConsole();
    }
    ~ConsoleLogger() {
        FreeConsole();
    }
    public static ILogger handle {
        get {
            lock ( cs ) { if ( instance == null ) instance = new ConsoleLogger(); }
            return instance;
        }
    }
    #endregion

    #region ILogger Member
    public void LogMessage(string message) {
        lock ( cs ) {
            String logString = getTimeString();
            logString += ( " -> \t " + message );
            Console.WriteLine(logString);
        }
    }
    #endregion

    #region Helper functions
    // ...
    #endregion
};

Now, I can have any class I'd like to implement ILoggable, and via the Extension Method LogingProvider.LogMessage I can call this.LogMessage("...") within these classes. If it was C++, I'd just use private inheritance instead.

Is this now good or bad design? Anything I can improve? Is there a way to provide classes with logging functionality without the extension method, but with similarly few changes?


回答1:


Your design seems a bit over-engineered at first sight. In this method:

public static void LogMessage(this ILoggable obj, String message) {
    logger.LogMessage(message);
}

the ILoggable obj is not used at all. Why do you need it then? Why not just have:

public static void LogMessage(String message) {
    logger.LogMessage(message);
}

and call it LoggingProvider.LogMessage(...)?

On a side note, take a look at Log4Net, this is the industry standard implementation of logging functionality.



来源:https://stackoverflow.com/questions/21882554/c-sharp-logging-design-extension-method-alternatives

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!