【问题标题】:Resolve type with IoC Container from within static Method从静态方法中使用 IoC 容器解析类型
【发布时间】:2014-03-03 22:31:41
【问题描述】:

当使用没有静态容器实例的 IoC 容器时(因为这会导致服务定位器反模式),如何从静态方法解析类型?

比方说,我有一个方法可以从文件中读取对象Document

public class Document {
    // when used with IoC, the Logger gets injected via property injection
    public ILogger Logger { get; set; }
    /* ... */
    public static Document Read (string filePath)
    {
        // need to resolve an ILogger at this point?
        Logger.Info ("reading in {0}", filePath);

        /* ...read in document an return a document instance here ... */

    }
}

代码是 C#,但同样的问题也适用于 Java 项目。

我知道一个简单的答案是“不要使用静态方法”,但鉴于该方法是无状态的,我认为这是静态方法有意义的情况之一。

使用单例 IoC 容器也会有所帮助,但众所周知这是一种反模式。

那么,解决问题的方法是什么?

【问题讨论】:

  • 如果它取决于注入的记录器实现的状态,它真的是“无状态”吗?
  • 如果我们已经在讨论最佳实践,我不确定您是否提出了一个令人信服的案例,即 Read() 应该是一个静态方法。
  • 嗯,很难说仅仅因为存在日志系统,就应该避免使用static 方法
  • @Dyna,仅仅因为你不能使用 IoC 并不严格意味着你不能使用静态方法。这只是意味着您不能通过使用 IoC 来注入依赖项——您必须以其他方式自己设置属性。需要使用这种资源是静态方法的一个缺点,但您可以自行决定权衡是否值得。
  • static 方法应该避免,因为它们很少需要。在您介绍的情况下(将文件读入文档对象)当然没有必要。

标签: c# java dependency-injection inversion-of-control static-methods


【解决方案1】:

虽然,我可以理解为什么将这个函数写为静态函数是有意义的,但答案很简单,DI 不适用于具有关联状态的静态方法。注入的属性是对象的状态,具有关联状态的静态方法被视为anti-pattern

DI 有时会强迫您使用纯(而非反)模式。

如果您坚持在您的情况下使用静态方法,我可以建议这些来涵盖您的选择。一切都不是完美的。

  1. 将注入的对象作为参数添加到函数中。 Document.Read(logger, filePath)。 如果您没有使用 IoC 框架,则替代方案是: new Document(logger).Read(filepath) 这或多或少是调用者的相同笨拙代码。
  2. 按照您的说明使用 ServiceLocator。
  3. 为类添加一个静态初始化方法,并注入它的所有依赖项(作为静态属性)。您必须在应用程序启动时调用此初始化。

【讨论】:

    猜你喜欢
    • 2018-06-14
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    相关资源
    最近更新 更多