当第一次遇到控制反转(IoC)时,它可能非常令人困惑。
这是怎么一回事?它解决了哪个问题?什么时候使用合适,什么时候不合适?
当第一次遇到控制反转(IoC)时,它可能非常令人困惑。
这是怎么一回事?它解决了哪个问题?什么时候使用合适,什么时候不合适?
当前回答
这里可以找到非常简单的书面解释
http://binstock.blogspot.in/2008/01/excellent-explanation-of-dependency.html
上面写着-
“任何非平凡的应用程序都由两个或多个类组成相互协作以执行一些业务逻辑。传统上,每个对象都负责获得自己的对其协作对象(其依赖项)的引用。应用DI时,对象在创建时被赋予其依赖性某个外部实体在系统换句话说,依赖项被注入到对象中。"
其他回答
“IoC”这个首字母缩略词和它所代表的名字似乎最让人困惑的是,这个名字太迷人了——几乎是一个喧嚣的名字。
我们真的需要一个名字来描述过程式编程和事件驱动编程之间的区别吗?好吧,如果我们需要的话,但我们是否需要选择一个全新的“比生活更大”的名字,它让人困惑而不是解决问题?
为了理解这个概念,控制反转(IoC)或依赖反转原理(DIP)涉及两个活动:抽象和反转。依赖注入(DI)只是为数不多的反转方法之一。
要了解更多信息,您可以在此处阅读我的博客
这是怎么一回事?
这是一种让实际行为来自边界之外的实践(面向对象编程中的类)。边界实体只知道它的抽象(例如面向对象编程中的接口、抽象类、委托)。
它解决了什么问题?
在编程方面,IoC试图通过使单片代码模块化、解耦其各个部分并使其可单元测试来解决单片代码。
什么时候合适,什么时候不合适?
这在大多数情况下都是合适的,除非您有只需要单片代码的情况(例如非常简单的程序)
所以上面的数字1。什么是控制反转?维护是它为我解决的首要问题。它保证我使用的是接口,这样两个类就不会彼此亲密。
使用温莎城堡这样的容器,它可以更好地解决维护问题。能够在不更改一行代码的情况下,将一个连接到数据库的组件替换为一个使用基于文件的持久性的组件,这是非常棒的(配置更改完成了)。
一旦你进入泛型,它会变得更好。想象一下,拥有一个接收记录并发布消息的消息发布者。它不在乎它发布了什么,但它需要一个映射器将记录中的内容转换为消息。
public class MessagePublisher<RECORD,MESSAGE>
{
public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo)
{
//setup
}
}
我写过一次,但现在如果我发布不同类型的消息,我可以向这组代码中注入许多类型。我还可以编写映射器,将相同类型的记录映射到不同的消息。将DI与Generics结合使用使我能够编写很少的代码来完成许多任务。
哦,是的,存在可测试性问题,但它们比IoC/DI的优势更为次要。
我绝对喜欢IoC/DI。
3.当你有一个中等规模的项目时,它会变得更加合适。我会说,当你开始感到疼痛时,它就变得合适了。
真的不明白为什么会有很多错误的答案,甚至被接受的答案也不太准确,这让人很难理解。真相总是简单明了的。
正如@Schneider在@Mark Harrison的回答中所评论的,请阅读Martin Fowler关于IoC的帖子。
https://martinfowler.com/bliki/InversionOfControl.html
我最喜欢的是:
这种现象就是控制反转(也称为好莱坞原则——“不要打电话给我们,我们会打电话给你”)。
为什么?
IoC的Wiki,我可以引用一段话。
控制反转用于增加程序的模块性并使其可扩展。。。随后在2004年由Robert C.Martin和Martin Fowler进一步推广。
Robert C.Martin:《清洁代码:敏捷软件工艺手册》的作者。
马丁·福勒:《重构:改进现有代码的设计》一书的作者。
对我来说,IoC/DI正在向调用对象推出依赖项。超级简单。
非技术性的答案是,在你打开引擎之前,你可以更换汽车的引擎。如果一切正常(界面),你就很好了。