反对控制容器倒置的争论

| 似乎每个人都在向IoC容器迈进。我已经尝试了一段时间,尽管我不想成为一个在高速公路上走错路的司机,但它仍然没有通过测试我的常识。让我解释一下,如果我的论点有误,请更正/启发我: 我的理解:当组合不同的组件时,IoC容器应该使您的生活更轻松。通过a)构造函数注入,b)setter注入和c)接口注入来完成。然后以编程方式或在容器读取的文件中“连接”这些文件。然后按名称召唤组件,然后在需要时手动进行投射。 我不明白的是: 编辑:(更好的措词) 如果正确设计了组件(使用IoC模式,松散耦合),则可以用更清晰的方式“联结”应用程序,为什么要使用不符合该语言的不透明容器?此“托管代码”如何获得非平凡的功能? (我听说过一些有关生命周期管理的内容,但我不一定理解这比自己动手做得更好/更快。) 原版的: 当按名称调用组件时,为什么要花所有的时间将组件存储在容器中,以不习惯于该语言的方式“将它们连接起来”,使用等同于“ goto标签”的东西,然后通过不进行手工转换而失去了静态类型语言的许多安全优点,而如果不这样做,它们将获得等效的功能,而是使用现代OO语言提供的所有酷炫的抽象功能,例如编程接口?我的意思是,实际上需要使用手头组件的零件必须知道它们在任何情况下都在使用它,在这里,您将使用最自然,惯用的方式进行“接线” -编程!     
已邀请:
肯定有人认为DI容器没有任何好处,这个问题是正确的。如果仅从对象组成的角度来看,容器的好处似乎微不足道。任何第三方都可以连接松散耦合的组件。 但是,一旦您超越了玩具场景,您应该意识到,与合作者建立联系的第三方必须承担的不仅仅是构图的责任。可能还会有退役问题,以防止资源泄漏。由于作曲者是知道给定实例是共享实例还是私有实例的唯一方,因此它还必须承担执行生命周期管理的角色。 当您开始使用共享和私有服务的组合来组合各种实例范围时,甚至将某些服务限定到特定的上下文(例如Web请求)时,事情都会变得很复杂。当然可以用穷人的DI编写所有代码,但不会增加任何业务价值-它是纯基础结构。 这样的基础结构代码构成了通用子域,因此创建可重用的库来解决此类问题很自然。这就是DI容器的确切含义。 顺便说一句,我知道的大多数容器都不使用名称来连接自身-它们使用自动装配,它将构造函数注入的静态信息与容器从接口到具体类的映射配置结合在一起。简而言之,容器本身了解这些模式。 DI不需要DI容器-它只是有用。 可以在文章何时使用DI容器中找到更详细的处理方法。     
我敢肯定,在这个问题上还有很多话要说,希望我会编辑此答案以在以后添加更多(希望更多的人会添加更多的答案和见解),但仅需简单说明几点你的帖子... 使用IoC容器是控制反转的一部分,而不是整个过程。您可以将控制反转用作设计构造,而无需依赖IoC容器框架。最简单的说,控制反转可以在这种情况下表示为“供应,不要实例化”。只要您的对象不是内部依赖于其他对象的实现,而是需要实例化的实现,被提供给他们,那么您正在使用控制反转。即使您没有使用IoC容器框架。 就您对接口的编程而言,我不确定您对IoC容器的使用经验(我个人最喜欢的是StructureMap),但是您肯定可以对IoC进行编程。至少在我如何使用它的整个思想上,是将接口(您的类型)与实现(注入的类)分开。依赖于接口的代码仅针对这些接口进行编程,并且在需要时注入这些接口的实现。 例如,您可以有一个“ 0”,它从类型为“ 1”的数据存储实例返回。您需要这些实例的所有代码均从提供的类型为“ 0”的对象中获取。在其他地方,创建
FooRepository
的实现,并将IoC配置为提供需要
IFooRepository
的任何地方。此实现可以从数据库,XML文件,外部服务等获取它们。在哪里都没有关系。该控件已被反转。使用类型为“ 1”的对象的代码不在乎它们来自何处。 明显的好处是您可以随时替换该实现。您可以将其替换为测试版本,根据环境更改版本等。但是请记住,在任何给定时间,您也不需要接口与实现的比例为1:1。 例如,我曾经在上一份工作中使用过代码生成工具,将大量DAL代码吐入一个类中。拆分它会很麻烦,但是将其配置为以特定的方法/属性名称将其全部吐出来并不是什么麻烦。因此,我为存储库编写了一堆接口,并生成了一个实现所有接口的类。对于生成的类,这很丑陋。但是我的应用程序的其余部分不在乎,因为它将每个接口视为自己的类型。 IoC容器为每个容器都提供了相同的类。 这样我们就可以快速启动并运行,而没有人在等待DAL开发。当我们继续使用接口的域代码进行工作时,初级开发人员的任务是创建更好的实现。这些实现后来被交换了,一切都很好。 如前所述,这一切都可以在没有IoC容器框架的情况下完成。确实,模式本身很重要。     
首先,什么是国际奥委会?这意味着创建从属对象的责任从主要对象中移走,并委托给第三方框架。我一直使用spring作为IOC框架,它为我们带来了很多好处。 促进接口编码和去耦-关键好处是IOC促进和去耦非常容易。您始终可以在主对象中注入接口,然后使用接口方法执行任务。主要对象不需要知道将哪个从属对象分配给接口。当您要使用其他类作为依赖项时,您需要的是在配置文件中将旧类交换为新类,而无需更改任何代码。现在您可以说可以使用各种界面设计模式在代码中完成此操作。但是IOC框架却在公园中漫步。因此,即使是新手,您也将成为利用各种接口设计模式(例如网桥,工厂等)的专家。 干净的代码-由于大多数对象创建和对象生命周期操作都委托给您从编写肉鸡点重复代码保存的IOC容器中进行。因此,您将获得一个更干净,更小,更易于理解的代码。 单元测试-IOC使单元测试变得容易。由于留下了解耦的代码,因此您可以轻松地单独测试解耦的代码。您还可以轻松地在测试案例中注入依赖关系,并查看不同组件之间的交互方式。 属性配置器-几乎所有应用程序都有一些属性文件,它们在其中存储应用程序特定的静态属性。现在,要访问这些属性,开发人员需要编写包装程序,这些包装程序将读取和解析属性文件,并以应用程序可以访问的格式存储属性。现在,所有IOC框架都提供了一种在特定类中注入静态属性/值的方法。因此,这再次成为在公园散步。 这些是我可以立即想到的一些观点,我相信还有更多。     

要回复问题请先登录注册