Dependency injection 使用依赖项注入容器时静态确定缺少的依赖项

Dependency injection 使用依赖项注入容器时静态确定缺少的依赖项,dependency-injection,inversion-of-control,static-analysis,Dependency Injection,Inversion Of Control,Static Analysis,使用依赖项注入容器时,执行resolve时会检测到缺少的依赖项。这是在运行时 本文描述了部分解决方案。这将有助于简化测试、调试和维护,但仍然需要执行测试来验证您的行为(特别是当您使用抽象工厂子解决方案进行运行时解析时): 当使用依赖项注入容器时,是否有一种方法可以静态地确定所有依赖项都将得到解决?简短回答:不,不能这样做 要做到这一点,需要能够将所有组件及其依赖项(容器元数据)表示为图形,以便对其进行分析。问题是,容器越复杂,实现这一点就越困难。以温莎为例。它使得依赖关系过于动态,无法用图形表

使用依赖项注入容器时,执行resolve时会检测到缺少的依赖项。这是在运行时

本文描述了部分解决方案。这将有助于简化测试、调试和维护,但仍然需要执行测试来验证您的行为(特别是当您使用抽象工厂子解决方案进行运行时解析时):


当使用依赖项注入容器时,是否有一种方法可以静态地确定所有依赖项都将得到解决?简短回答:不,不能这样做

要做到这一点,需要能够将所有组件及其依赖项(容器元数据)表示为图形,以便对其进行分析。问题是,容器越复杂,实现这一点就越困难。以温莎为例。它使得依赖关系过于动态,无法用图形表示。惰性组件加载程序、处理程序选择器、工厂、组件模型贡献者、子解析器都参与了该过程,它们可以是任意用户代码,这使得静态分析变得不可能

静态分析对于一个简单的容器可能是可行的,但是这个假设的容器对于现实世界的项目来说是非常无用的

所以和往常一样,这是一种折衷,我们能做的最好的事情就是做一些测试,测试容器中所有注册组件的实际分辨率。StructureMap有一个AssertConfigurationsValid()方法来实现这一点


即便如此,可能还有一些更微妙的错误没有被发现,比如。

简短回答:不,这是不可能的

要做到这一点,需要能够将所有组件及其依赖项(容器元数据)表示为图形,以便对其进行分析。问题是,容器越复杂,实现这一点就越困难。以温莎为例。它使得依赖关系过于动态,无法用图形表示。惰性组件加载程序、处理程序选择器、工厂、组件模型贡献者、子解析器都参与了该过程,它们可以是任意用户代码,这使得静态分析变得不可能

静态分析对于一个简单的容器可能是可行的,但是这个假设的容器对于现实世界的项目来说是非常无用的

所以和往常一样,这是一种折衷,我们能做的最好的事情就是做一些测试,测试容器中所有注册组件的实际分辨率。StructureMap有一个AssertConfigurationsValid()方法来实现这一点


即使如此,也可能有一些更微妙的错误没有被捕获,例如。

托管可扩展性框架(MEF)可以做到这一点。为了使分析准确,您需要遵循一些最佳实践,但在其他方面效果良好

要分析一组部件,请使用命令行工具-请参阅。这可以从Visual Studio或持续集成服务器中的生成脚本运行

您可以使用MefContrib项目的VisualMefx可视化地(同样是在一组程序集上)执行此操作-请参阅


MEF通过非常声明性(配置的标准属性)和使用惰性工作的底层组合模型来支持此功能(它可以在不创建任何实例的情况下构建图形……这需要一点时间)。托管可扩展性框架(MEF)可以做到这一点。为了使分析准确,您需要遵循一些最佳实践,但在其他方面效果良好

要分析一组部件,请使用命令行工具-请参阅。这可以从Visual Studio或持续集成服务器中的生成脚本运行

您可以使用MefContrib项目的VisualMefx可视化地(同样是在一组程序集上)执行此操作-请参阅


MEF支持这一功能,它既具有很强的声明性(配置的标准属性),又使用了一个工作缓慢的底层组合模型(它可以在不创建任何实例的情况下构建图形……这需要一点时间让您费解。)

除了Mauricio所说的,Windsor 2.5有一个功能,在诊断缺少依赖项的问题或只是查看容器中的组件时,您可能会发现该功能很有用

我在博客上写了它的测试版。它现在非常有用,并且和温莎的所有东西一样——它是可扩展的,所以你可以在列表中列出你自己的项目


除了Mauricio所说的,Windsor 2.5还有一个功能,在诊断缺少依赖项的问题或只是查看容器中的组件时,您可能会发现该功能很有用

我在博客上写了它的测试版。它现在非常有用,并且和温莎的所有东西一样——它是可扩展的,所以你可以在列表中列出你自己的项目


可能没有依赖项注入容器。但是,您可以在没有容器的情况下手动执行依赖项注入。例如:

var foo = new Foo();
var bar = new Bar(foo);
var program = new Program(bar);
program.Run();
如果它编译了,那么所有依赖项都在那里


然而,一旦依赖关系图变得足够大,以至于你无法将它完全保存在头脑中(特别是在混合中抛出一些循环依赖关系时),麻烦就迫在眉睫了。如果重构涉及重新排列依赖项,那么调整构造函数调用的顺序将变得非常困难。

可能不需要依赖项注入容器。但是,您可以在没有容器的情况下手动执行依赖项注入。例如:

var foo = new Foo();
var bar = new Bar(foo);
var program = new Program(bar);
program.Run();
如果它编译了,那么所有依赖项都在那里

然而,一旦依赖关系图变得足够大,以至于你无法将它完全保存在头脑中(特别是在混合中抛出一些循环依赖关系时),麻烦就迫在眉睫了。如果重构涉及到重新排列依赖项,那么它将是