当使用没有静态容器实例的 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 容器也会有所帮助,但众所周知,这是一种反模式。
那么,解决这个问题的方法是什么?
最佳答案
虽然,我可以理解为什么将此函数编写为静态是有意义的,但答案很简单,DI 与具有关联状态的静态方法配合得不好。注入(inject)的属性是对象的状态,具有关联状态的静态方法被视为 anti-pattern .
DI 有时会迫使您使用纯(而非反)模式。
如果您坚持在您的情况下使用静态方法,我可以建议这些来涵盖您的选择。一切都不是完美的。
- 将注入(inject)的对象作为参数添加到函数中。
Document.Read(记录器,文件路径)
。 如果您没有使用 IoC 框架,替代方案是:新文档(记录器).Read(文件路径)
对于调用者来说,这或多或少是同样笨拙的代码。 - 按照您的说明使用 ServiceLocator。
- 向类添加静态初始化方法,并注入(inject)其所有依赖项(作为静态属性)。您必须在应用程序启动时调用此初始化。
关于c# - 从静态方法中使用 IoC 容器解析类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22158940/