C# 从静态方法中使用IoC容器解析类型
当使用没有静态容器实例的IoC容器时(因为这将导致服务定位器反模式),如何从静态方法解析类型 比如说,我有一个方法可以从文件中读取对象C# 从静态方法中使用IoC容器解析类型,c#,java,dependency-injection,inversion-of-control,static-methods,C#,Java,Dependency Injection,Inversion Of Control,Static Methods,当使用没有静态容器实例的IoC容器时(因为这将导致服务定位器反模式),如何从静态方法解析类型 比如说,我有一个方法可以从文件中读取对象文档: public class Document { // when used with IoC, the Logger gets injected via property injection public ILogger Logger { get; set; } /* ... */ public static 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与具有关联状态的静态方法不兼容。注入的属性是对象的状态,具有关联状态的静态方法被视为对象
DI有时会强制您使用纯(非反)模式
如果您坚持在您的案例中使用静态方法,我可以建议这些方法来涵盖您的选项。并非都是完美的
将注入的对象作为参数添加到函数中。
Document.Read(记录器,文件路径)
。
如果您没有使用IoC框架,那么备选方案是:
新文档(记录器)。读取(文件路径)
对于调用者来说,这或多或少是同样笨拙的代码
如您所述,使用ServiceLocator
向类中添加静态初始化方法,并注入它的所有依赖项(作为静态属性)。您必须在应用程序启动时调用此初始化
如果它取决于记录器的注入实现的状态,那么它真的是“无状态”的吗?如果我们已经在讨论最佳实践,我不确定您是否提出了一个令人信服的理由,即Read()
应该是一个静态方法。很难仅仅因为存在日志系统,静态
方法应该是avoided@Dyna,仅仅因为你不能使用IoC并不意味着你不能使用静态方法。这只是意味着不能通过使用IoC注入依赖项——必须通过其他方式自己设置属性。使用这种方法的必要性是静态方法的一个缺点,但这取决于您确定折衷是否值得。应该避免使用静态方法,因为它们很少是必需的。在您介绍的情况下(将文件读入文档对象),这当然不是必需的。