如果我理解正确,在经典的3层/ n层体系结构中,目标是最终将责任分开,使每个层不必知道内部正在进行/正在使用的内容在较低的层次。
但是,如果每个层(特别是业务)中的对象被构造为可测试的,则它们的依赖关系被定义为其公共契约的一部分(当测试具有第3层对象依赖性的第二层对象时,模拟/存根淘汰第3层对象并将其提供给第2层对象)。这意味着在实现时,第一层负责获取用于构造第二层对象的第三层依赖项。如果它是一个非常乏味的对象,但我不反对这一点,但如果它是一个需要连接字符串的数据访问组件,那么第一层不应该对此负责。除此之外,您拥有的依赖关系越多,顶层负责实例化并传递其所使用的洋葱片中每个对象的所有依赖关系。
我曾经见过这个被破坏的问题的唯一方法是使用IoC,但我工作的情况是该选项不在桌面上。是否有其他方法可以将代码构造为可测试但不会面临为顶层中的每个层实例化/提供依赖性的问题?我应该提一下我在网络应用程序中工作。
(我已经过this帖子作为对规则的复习。")
编辑:我想我可以总结这个问题:如果不使用某种IoC容器或引导程序,是否有办法将代码构造为可测试的,并不违反依赖深度原则,洋葱中的每一层都只能引用它下面的层吗?答案 0 :(得分:1)
它不是关于顶层本身,而是关于将初始化您的应用程序的bootstraper。根据架构的其余部分,它可以负责在应用程序的顶层启动入口点,也可以只是顶层初始化的一部分(甚至可以与IoC框架一起使用)。
.NET中的示例:
如果您正在构建独立应用程序,则可以将内容初始化为主执行路径的一部分,并且只有在所有内容都已初始化时,您才会启动入口点。对于Web应用程序或Web服务,此类引导程序通常在应用程序启动处理程序中进行,并且在处理HTTP请求时使用您的层。
顺便说一下。问题应该是关于IoC容器。不是关于IoC本身。 IoC是从外部控制内部逻辑的方法 - 通过注入依赖关系来实现。它是易于测试的应用程序的主要方法。 IoC容器是为您构建依赖层次结构的框架的一部分。
答案 1 :(得分:0)
您可以在没有IoC容器的情况下反转控制,正如@LadislavMrnka所解释的那样。
您可以执行事件依赖性倒置,并从松散耦合和可测试性中受益,而无需执行基于接口的IoC。事件和higher-order functions是两种方法。
您可以解耦部分代码库,无需一次完成所有操作。一个对象可以由消耗它的对象决定和/或注入它的依赖关系,你不必将它一直推迟到一个引导程序。
考虑到这一点,你问题的答案是"是"并以许多不同的方式:)
我认为从小做起,确实是一个好主意,首先让一些组件可测试(并经过测试),而不是试图在一次漫长,乏味和冒险的重构中预测一切可能性和IoC-ify 。当大部分代码库经过测试和清理后,IoC可以在以后出现。