[英]Accessing logging functionality from a class library
I have a solution with two projects, my WPF application project which references the second project, a class library. 我有一个包含两个项目的解决方案,我的WPF应用程序项目引用了第二个项目,一个类库。 The WPF application uses Caliburn.Micro.
WPF应用程序使用Caliburn.Micro。 I would like some classes in the library to log messages through Caliburn.Micro's logging facility (which I've set up with log4net, but that should be irrelevant).
我想库中的一些类通过Caliburn.Micro的日志工具(我用log4net设置,但这应该是无关紧要的)记录消息。
To see if this would work, I put the following class into my library to see if anything would show up in my log, and called it from one of my viewmodels: 为了查看这是否有效,我将以下类放入我的库中,以查看是否有任何内容会显示在我的日志中,并从我的一个视图模型中调用它:
public class TempClass {
private static ILog Log = LogManager.GetLog(typeof(TempClass));
public static void LogSomething(string something) {
Log.Info(something);
}
}
It didn't work. 它没用。
The class library can't reference my WPF application's project because that would cause a circular reference. 类库无法引用我的WPF应用程序的项目,因为这会导致循环引用。
What is a good solution to this problem? 什么是这个问题的好方法?
EDIT 编辑
A bit of additional information that might be useful. 一些可能有用的附加信息。 LogManager is a static class inside Caliburn.Micro.DLL, and has a public static GetLog field:
LogManager是Caliburn.Micro.DLL中的静态类,并具有公共静态GetLog字段:
public static Func<Type, ILog> GetLog = type => NullLogInstance;
In my bootstrapper, I'm setting that to 在我的引导程序中,我正在设置它
LogManager.GetLog = type => new Log4netLogger(type);
If I set a breakpoint in the Log4netLogger constructor, it isn't hit when the GetLog() call is made to get my ILog instance in TempClass. 如果我在Log4netLogger构造函数中设置断点,则在调用GetLog()以在TempClass中获取我的ILog实例时不会触发它。
Here is the implementation of Log4netLogger if it helps: 如果有帮助,这是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);
}
}
It turns out the problem was using a field initializer. 事实证明问题是使用字段初始化程序。 I believe this was being called before my bootstrapper had the opportunity to assign another delegate to GetLog.
我相信这是在我的引导程序有机会将另一个委托分配给GetLog之前调用的。 Here is the new TempClass which works:
以下是新的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);
}
}
You could use Dependency Injection to solve this problem: http://msdn.microsoft.com/en-us/library/aa973811.aspx 您可以使用依赖注入来解决此问题: http : //msdn.microsoft.com/en-us/library/aa973811.aspx
(You could also use ServiceLocator: http://www.martinfowler.com/articles/injection.html although, you will find mixed opinions on it. Some people like it, some say that Service Locator is evil: http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/ (你也可以使用ServiceLocator: http : //www.martinfowler.com/articles/injection.html虽然,你会发现它的意见不一。有些人喜欢它,有人说服务定位器是邪恶的: http:// blog .ploeh.dk / 2010/02/03 / ServiceLocatorisanAnti点模式/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.