如何使用Spring Framework确保所需的依赖项已包含在我的应用程序中?

7
这将是一个比较棘手的问题,但是我们可以试着解答一下。
我们正在使用 Delphi Spring Framework(http://code.google.com/p/delphi-spring-framework/)。
假设我有一个名为 UnitA 的单元,其中声明了 InterfaceA,并由 ClassA 实现。同样,我有一个名为 UnitB 的单元,其中声明了 InterfaceB,并由 ClassB 实现。它们都在各自的初始化部分中向 Spring 容器注册了其接口和类。
InterfaceA 依赖于 InterfaceB,但是因为我们使用了 Spring,UnitA 在其 uses 子句中没有 UnitB。换句话说,我们已经完成了工作——我们已经将 UnitA 和 UnitB 解耦,但我们仍然能够让 InterfaceA 依赖于 InterfaceB。
然而,在上述情况下,我们需要确保项目中同时包含 UnitA 和 UnitB,以便解决依赖关系。
现在,想象一下我们开始一个新项目。该项目使用 UnitA,但开发人员并没有意识到如果要使用 UnitA,则还必须将 UnitB 包含在项目中。不会有编译器错误,因为依赖关系在运行时而不是编译时解决。
因此,问题就在于:如何确保在应用程序部署之前知道对 UnitB 的依赖关系?
在复杂的应用程序中,我们可以预见到一种情况,即尽管经过了彻底的测试,但某个代码路径可能长时间没有被执行,因此在部署之前无法发现缺少的依赖项。
我们实现了一个系统,在每个接口解析调用的同时伴随着一个 Requires 调用,该调用在启动时检查并引发异常,以确保我们能看到错误。但我们想知道是否有一种“最佳实践”或标准方法来检测或处理这个问题。
补充:Java 和其他语言中是否存在这个问题?

1
在Java中,如果通过外部配置文件进行连线,则存在问题。一些DI容器(例如Google Guice)在应用程序启动过程中进行配置,未解决的依赖关系会导致编译时错误。 - mjn
1
这就是我喜欢(开玩笑)依赖反转的原因:出现运行时错误,而不是编译时错误。简而言之,依赖关系很糟糕,没有依赖关系更糟糕。 :-) - Warren P
2个回答

5
你需要使用类似 Maven 或者 Ivy 的依赖管理工具。一旦你这样做了,你就可以说 UnitA 依赖于 UnitB,一旦有人将 UnitA 添加为依赖项,该工具(无论是 Maven 还是 Ivy)都会强制下载依赖项并将其包含在你的项目中。
Maven 本身有一个 Eclipse 插件,即使你已经在当前工作空间中拥有其他项目,它也能检测到。

好的,实际上,这个框架本身并不支持这个功能,你需要一个外部工具来通过静态分析来检查依赖关系,对吧? - Nick Hodges

2
我有点困惑。松散耦合是使用接口而不是IoC容器实现的。如果InterfaceB在UnitB中声明,那么UnitA自然会使用它。
接口的实现是另一回事。这些实现需要引用它们实现的接口和它们使用的任何接口,但不应该引用任何其他实现。
我没有在Delphi中使用Spring,但我熟悉其他IoC容器。如果行为类似,则您正在注册接口及其实现。当调用resolve时,您要传递接口的名称或关于接口的其他信息(类型信息),并期望IoC容器返回您请求的接口的引用。哪个实现位于该接口背后是由注册的实现以及解析请求的规则决定的。
如果您请求的接口从未注册过,则会出现异常。一些IoC容器可以通过单个调用解析整个依赖关系链。
您正在寻求一种方法,在构建时确定是否会在运行时解析依赖项,但依赖项直到运行时才注册。我认为无论使用什么工具,都无法保证这一点。
UnitA应该在其uses子句中包含UnitB。UnitA和UnitB中接口的实现可以并且可能应该位于与A和B不同的单元中,特别是如果每个接口都有多个实现。
在项目中使用UnitA的开发人员将被迫同时包含UnitB。如果他们在新项目中使用测试驱动开发,他们很快就会发现需要为InterfaceA和InterfaceB提供实现(即使它们只是模拟),以使他们的测试通过。
坦白说,如果一个关键依赖被忽视,并且项目在没有它的情况下部署,那么测试就不够彻底。单元测试可能无法捕捉到这一点,但这正是一套集成测试通常会捕捉到的问题。
我建议使用FitFitnesse进行集成测试(虽然我不确定Fit4Delphi项目的成熟度如何)。这些测试可以由任何能够编写文档或编辑wiki的人编写,开发者只需编写允许测试驱动生产代码的类。如果正确设置,您可以针对实际发布版本的项目运行大多数集成测试。

谢谢,肯恩。回答得很好。这里的关键是你所说的:你无法在编译时解决依赖关系,需要测试来确保依赖关系。 - Nick Hodges

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接