5

我在我的应用程序中使用 Castle Windsor 的控制反转。当应用程序首次加载时,IWindsorContainer.Resolve将组件(特别是工厂)解析为实例。

例如,ILoggerFactory被解析为MyCustomLoggerFactory(或任何实现ILoggerFactory),其方法CreateLogger()创建一个记录器。我想让每个班级都打电话ILoggerFactory.CreateLogger()。但是,我不想将 an 传递给ILoggerFactory每个类的构造函数。

每个类如何访问特定的ILoggerFactory工厂来使用而不必IWindsorContainer.Resolve每次都调用?

4

2 回答 2

3

据我所知,有三种方法可以从 windsor 容器中获取依赖项(顺便说一下,除了可能是一些底层类之外,您不需要显式解析任何内容,只需确保它都已在容器中注册并且为您连接了依赖项):

  1. 添加构造函数参数(这被认为是必需的依赖项)
  2. 向类添加属性(这被认为是可选依赖项)
  3. 获取 IWindsorContainer 实例并调用 Resolve(这通常是个坏主意)

通常,对于专门进行日志记录,您会将其设为可选依赖项,因此请选择选项 2 并执行类似操作(我使用了您的 ILoggerFactory 想法,实际上我不会为此定义自己的工厂 - 见下文):

private ILoggerFactory _loggerFactory = LoggerFactory.NullLoggerFactory;

public ILoggerFactory LoggerFactory
{
    get { return _loggerFactory; }
    set { _loggerFactory = value; }
}

这样,在您的代码中,您可以使用 LoggerFactory 属性,如果尚未将一个属性添加到容器中,您将获得“null”版本(这只是 ILoggerFactory 的一个实例,它创建一个什么都不做的记录器),如果它有你得到了真正的版本(你可以在使用它时检查null,或者如果你知道会有一个就使用它)。您在需要记录器的类上定义此属性,然后就完成了。

旁白

顺便说一句,您可以使用 Windsor 中的日志记录工具之类的东西- 我对此有一个小问题,因为我真的不希望在我的代码库中使用 Windsor 接口,所以我过去所做的事情已经定义我自己的 ILogger 接口(以及它的空实现),然后创建了一个“城堡记录器代理”,它实现了我的 ILogger 接口,但依赖于城堡 ILogger,这是它调用来执行实际日志记录的方法。这样,我可以将其分离到它自己的程序集中,并且我的应用程序不知道 Windsor 正在注入依赖项。

也许你不在乎,只是想我会提到它。

于 2012-04-18T06:58:14.227 回答
2

如果您不想污染您的 API,可以在此处使用环境上下文模式,如下所示:

public abstract class Logger
{
    static Logger()
    {
        Current = new DefaultLogger();
    }

    public static Logger Current { get; set; }

    // your Logger members
    public abstract void Log();
}

public class DefaultLogger : Logger
{
    public override void Log()
    {
        //do something
    }
}
于 2012-04-18T08:11:11.257 回答