C#测井设计:扩展方法,替代方案?

C#测井设计:扩展方法,替代方案?,c#,logging,interface,extension-methods,C#,Logging,Interface,Extension Methods,我想写一个记录器,可以很容易地附加到我当前项目中的任何类。对于开发,将消息记录到控制台会很方便,而在最终版本中,我希望记录到文件或其他东西。只需编辑几行代码,或者理想情况下编辑一个设置文件,就可以更改行为 到目前为止,我掌握的是这个班级结构: public interface ILogger { void LogMessage(String message); // ... other logging functions (exceptions, time etc.) don't

我想写一个记录器,可以很容易地附加到我当前项目中的任何类。对于开发,将消息记录到控制台会很方便,而在最终版本中,我希望记录到文件或其他东西。只需编辑几行代码,或者理想情况下编辑一个设置文件,就可以更改行为

到目前为止,我掌握的是这个班级结构:

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
};
现在,我可以拥有我想要实现的任何类
ilogable
,并且通过扩展方法
LogingProvider.LogMessage
我可以在这些类中调用
this.LogMessage(“…”
)。如果是C++,我只会使用私有继承。
这是好的还是坏的设计?有什么可以改进的吗?有没有一种方法可以在不使用扩展方法的情况下为类提供日志记录功能,但只需做一些类似的更改?

乍一看,您的设计似乎有点过度设计。在这种方法中:

public static void LogMessage(this ILoggable obj, String message) {
    logger.LogMessage(message);
}
根本不使用
ilogable obj
。那你为什么需要它?为什么不干脆:

public static void LogMessage(String message) {
    logger.LogMessage(message);
}
并称之为
LoggingProvider.LogMessage(…)


请注意,这是日志功能的行业标准实现。

这可能应该移到您的右侧,
obj
未使用。但是我需要它来限制某些类的日志记录,即那些实现
ilogable
@Matz的类,我真的不理解你的评论。扩展方法在设计上是公共的,因此人们可以从任何地方登录,只要他们在某个iLogable对象上调用该方法(无论是否相关)。