【问题标题】:Accessing logging functionality from a class library从类库访问日志记录功能
【发布时间】:2013-08-23 03:37:34
【问题描述】:

我有一个包含两个项目的解决方案,我的 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);
    }
}

【问题讨论】:

  • 您能否将 Caliburn.Micro 移至其自己的项目并让您的 WPF 和 CL 项目引用它?
  • 两个项目都引用了 Caliburn.Micro.DLL,但我上面的实验让我觉得 LogManager.GetLog() 返回的记录器没有连接到另一个程序集。

标签: c# .net logging caliburn.micro


【解决方案1】:

原来问题出在使用字段初始化程序。我相信这是在我的引导程序有机会为 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);
    }
}

【讨论】:

    【解决方案2】:

    你可以使用依赖注入来解决这个问题: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/

    【讨论】:

    • Caliburn.Micro 支持 IoC,我的应用程序正在使用它。问题是,IoC 容器也在应用程序项目中。
    • 不过没关系,其实这就是你想要的。 (您的组合根应该在您的应用程序层中)。你的框架类应该使用构造函数注入来接收记录器,或者你可以定义一个框架级的 IServiceLocator,在你的应用程序中初始化它,然后你的框架代码会从定位器请求日志服务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 2012-11-07
    • 1970-01-01
    相关资源
    最近更新 更多