3

我有一个包含两个项目的解决方案,我的 WPF 应用程序项目引用了第二个项目,一个类库。WPF 应用程序使用 Caliburn.Micro。我希望库中的一些类通过 Caliburn.Micro 的日志记录工具(我已经使用 log4net 设置,但这应该无关紧要)记录消息。

为了看看这是否可行,我将以下类放入我的库中以查看我的日志中是否会显示任何内容,并从我的一个视图模型中调用它:

public class TempClass {
    private static ILog Log = LogManager.GetLog(typeof(TempClass));

    public static void LogSomething(string something) {
        Log.Info(something);
    }
}

它没有用。

类库无法引用我的 WPF 应用程序的项目,因为这会导致循环引用。

这个问题有什么好的解决方案?

编辑

一些可能有用的附加信息。LogManager 是 Caliburn.Micro.DLL 中的一个静态类,并且有一个公共静态 GetLog 字段:

public static Func<Type, ILog> GetLog = type => NullLogInstance;

在我的引导程序中,我将其设置为

LogManager.GetLog = type => new Log4netLogger(type);

如果我在 Log4netLogger 构造函数中设置断点,则在调用 GetLog() 以在 TempClass 中获取我的 ILog 实例时不会命中该断点。

如果有帮助,这里是 Log4netLogger 的实现:

internal class Log4netLogger : ILog {
    private readonly log4net.ILog InnerLogger;

    public Log4netLogger(Type type) {
        InnerLogger = log4net.LogManager.GetLogger(type);
    }

    public void Error(Exception exception) {
        InnerLogger.Error(exception.Message, exception);
    }

    public void Info(string format, params object[] args) {
        InnerLogger.InfoFormat(format, args);
    }

    public void Warn(string format, params object[] args) {
        InnerLogger.WarnFormat(format, args);
    }
}
4

2 回答 2

3

事实证明问题出在使用字段初始化程序。我相信这是在我的引导程序有机会为 GetLog 分配另一个代表之前调用的。这是有效的新 TempClass:

public class TempClass {
    private static ILog Log;

    public static void LogSomething(string something) {
        if (Log == null)
            Log = LogManager.GetLog(typeof(TempClass));

        Log.Info(something);
    }
}
于 2013-08-20T23:37:23.970 回答
1

你可以使用依赖注入来解决这个问题:http: //msdn.microsoft.com/en-us/library/aa973811.aspx

(你也可以使用 ServiceLocator: http: //www.martinfowler.com/articles/injection.html虽然,你会发现它的意见不一。有人喜欢它,有人说 Service Locator 是邪恶的:http://blog .ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/

于 2013-08-20T22:40:03.040 回答