为什么自动注册依赖项是邪恶的

图片



对于各种编程语言,有许多类型为Simple Injector的项目,这些项目允许通过类,接口或名称空间的名称(有时甚至是文件夹的名称)在某些情况下注册通过该功能组合在一起的一个类或整个类组。这样做的目的是自动实例化对象,而无需显式指定其依赖关系。为了进一步实例化,通过寄存器中的通用功能对一组对象进行的这种注册,我称为依赖性的自动注册。



如果在将其注册到依赖项寄存器中时显式实例化一个类,那么这不是本文的主题。



那怎么了?



在这篇文章中,我将与使用自动依赖项注册的项目分享我的挫败感。让我们去吧。



运行时vs编译时间



使用自动依赖项注册工具,我们将检查已注册依赖项的完整性转移到运行时。也就是说,如果在启动程序时我们没有执行代码所需的接口的实现,那么我们将最好在应用程序启动时找到它,而在最坏的情况下-我们已经在系统运行期间以及从用户那里找到了它。



这是一个例子。例如,如果在项目中某些类是通过其名称空间注册的,并且您有时将其从类中移走了,那么您将在运行时了解问题。通过界面自动注册也会发生同样的情况,唯一的区别是移动不会有问题,但是删除界面会导致问题,您可以在启动应用程序后了解一下。



重构要复杂得多



不仅重构,而且学习代码也变得非常困难。这是因为在使用依赖项的自动注册时,将失去对开发环境的现代功能的访问,这将使我们能够一键找出谁在使用此类(查找参考)并回答以下问题:



  • 我可以取消这个课程吗?
  • 我可以将此类移到另一个名称空间/文件夹吗?


等等



除了我们没有机会在编译期间检查所需依赖项的完整性这一事实之外,任何重构都是希望我们拥有测试,依赖树验证等形式的运行时机制。希望它能起作用。应该注意的是,这些机制不仅不能保证100%的代码组成是正确的,而且还比编译慢得多。



隐藏系统的真正复杂性



手动实例化类及其所有依赖项时,可能会对所有执行此操作的文件的怪物感到害怕。查看用于实例化类的数千行代码,并在使用自动依赖项注册时将它们与十二行代码进行比较,我真的很想屈服于诱惑并转到“黑暗面”。



但是这数千行对象实例化代码告诉我们什么?这个模块非常复杂,庞大,因此,我们应该考虑通过分配子模块(本身明确实例化其依赖关系)来构造它,或者将该模块分成几个模块。



听起来可能很抽象,但是如果从实例中消除实例化数百个对象这样的尴尬时刻,则会导致项目规模无法控制地增长,因此,我们错过了将其划分为多个项目的时刻。



额外的依赖



通过注册依赖项而不控制它们的使用,我们迟早会遇到一种情况,即在应用程序启动时,注册的类明显多于实际需要的类。简单地添加到文件夹或接口的实现通常会导致此类的注册。



概要



是否有可能生活在所有这些不利条件中而不注意到它们?当然!但是我相信这会养成错误的发展习惯。关键是代码的编译和键入是检查系统正确性的工具。拒绝它们,我们发现系统变得脆弱,因此开发人员害怕更改其中的任何内容。而且,开发人员担心更改代码已经导致这样一个事实,即代码库的质量降低了,此后,对此类代码进行更改将成为昂贵的过程。



自动依赖项注册有什么好处?



真的,有什么好处?我建议在评论中讨论为什么这种方法越来越受欢迎。当然,他的读者中有很多粉丝。



All Articles