我有一个包含两个项目的解决方案,我的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);
}
}
答案 0 :(得分: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);
}
}
答案 1 :(得分:1)
您可以使用依赖注入来解决此问题:http://msdn.microsoft.com/en-us/library/aa973811.aspx
(你也可以使用ServiceLocator:http://www.martinfowler.com/articles/injection.html,你会发现它的意见不一。有些人喜欢它,有人说服务定位器是邪恶的:http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/