控制反转与依赖注入


525

根据马丁·福勒(Martin Fowler)论文,控制反转是程序控制流反向的原理:外部源(框架,服务,其他组件)代替程序控制程序流,而由程序控制流它。就像我们将某些东西插入其他东西一样。他提到了有关EJB 2.0的示例:

例如,会话Bean接口定义了ejbRemove,ejbPassivate(存储到辅助存储)和ejbActivate(从被动状态恢复)。您不必控制何时调用这些方法,而可以控制它们的作用。容器给我们打电话,我们不给它打电话。

这导致框架和库之间的差异:

控制反转是使框架与库不同的关键部分。库本质上是您可以调用的一组函数,这些天通常组织成类。每个调用都会执行一些工作,并将控制权返回给客户端。

我认为,DI是IOC的观点意味着对象的依赖关系被颠倒了:与其控制自己的依赖关系,不如生命周期……还有其他事情为您服务。但是,正如您手动告诉我的那样,DI不一定是IOC。我们仍然可以拥有DI而没有IOC。

但是,在本文中(来自pococapsule,这是另一个C / C ++的IOC框架),它表明,由于IOC和DI,IOC容器和DI框架要优于J2EE,因为J2EE将框架代码混合到了组件中,因此不会使其成为普通的Java / C ++对象(PO​​JO / POCO)。

除依赖注入模式以外的控制容器的反转(归档链接)

进一步阅读以了解旧的基于组件的开发框架有什么问题,这导致了上面的第二篇论文:控制反转的原因和内容(归档链接)

我的问题:什么是IOC和DI?我很困惑。基于pococapsule,IOC不仅仅是对象或程序员与框架之间的控制反转。


2
以下是有关IoC VS DI(依赖注入)与SL(服务定位器)的主题文章:tinyurl.com/kk4be58-摘录自URL:IoC VS DI(依赖注入)?国际奥委会在那里流控制的一般概念倒置从客户端代码框架,其中“做了为客户”。SL(服务定位器)和DI(依赖项注入)是源于IoC的两个设计模式。
Swab.Jat 2014年

加上我的两分钱,如果有人对依赖注入对咖啡店主题的帮助感兴趣,我在这里写了一篇文章:digigene.com/design-patterns/dependency-injection-coffeeshop
Ali Nem


依赖倒置:依赖抽象,而不依赖具体。控制反转:Main与Abstract,以及Main是系统的粘合剂。这些都是一些很好的帖子在谈论这一点:coderstower.com/2019/03/26/... coderstower.com/2019/04/02/... coderstower.com/2019/04/09/...
丹尼尔·安德烈斯·佩莱斯·洛佩兹

阅读有关此深,它会清除所有martinfowler.com/articles/...
Dushman

Answers:


644

IoC是一个通用术语,表示的不是让应用程序调用框架中的方法,而是框架调用应用程序提供的实现。

DI是IoC的一种形式,其中实现通过构造函数/设置程序/服务查找传递到对象中,该对象将“依赖”该对象以使其行为正确。

不使用DI的IoC例如将是Template模式,因为只能通过子类来更改实现。

DI框架旨在利用DI并可以定义接口(或Java中的注释),以使其易于实现。

IoC容器是可以在编程语言之外工作的DI框架。在某些情况下,您可以配置要在侵入性较小的元数据文件(例如XML)中使用哪些实现。使用某些工具,您可以执行IoC,就像在切入点注入实现一样,这通常是不可能的。

另请参阅此Martin Fowler的文章


2
感谢您的回答。但是另一篇论文建议使用IOC,IOC容器要比EJB优越得多,而Martin Fowler建议EJB是IOC的典型示例。
Amumu

5
EJB管理确实是IoC的典型示例。您可以从EJB的生命周期由容器而不是程序员管理的事实中看到它。程序员不会创建或销毁EJB实例,因为控件是委派给服务器的。这就是IoC的概念:外部代码控制何时调用您的代码,这通常与大多数情况下的操作相反
brandizzi

2
IoC是一个通用术语,表示的不是让应用程序调用框架中的方法,而是框架调用应用程序提供的实现。您能对此做更多解释吗?
Imad Alazani 2013年

21
又名好莱坞原则,“不要打电话给我们,我们会打电话给您”。将调用留给框架而不是应用程序来完成。
加勒特·霍尔

@ImadAlazani,您最好阅读Garrett随附的文章,这是有关将控件从应用程序代码转换为框架的详细讨论。
MengT 2014年

210

简而言之,IoC是一个更广泛的术语,包括但不限于DI

控制反转(IoC)一词最初是指一种由整体框架或运行时控制程序流程的编程方式

在DI得名之前,人们开始将管理依赖项的框架称为“控制容器的倒置”,不久,IoC的含义逐渐向该特定含义漂移:对依赖项的控制倒置。

控制反转(IoC)意味着对象不会创建它们依靠其进行工作的其他对象。相反,他们从外部源(例如xml配置文件)获取所需的对象。

依赖注入(DI)意味着无需对象干预即可完成此操作,通常是通过传递构造函数参数和设置属性的框架组件完成的。


1
好像IoC只是Depency Inversion原理的另一个术语,不是吗?
Todd Vance

@ToddVance-是的,我认为IoC和DIP是同一回事。DIP和DI不是同一件事。没有DI即可完成IoC,但没有IoC则无法完成DI。
Eljay

2
@ToddVance-不,DIP和IoC不是同义词,也不相关。
TSmith

3
哈,这就是为什么我在此线程上...“控制反转与依赖注入”
Todd Vance

50

在此处输入图片说明
资源

国际奥委会 oid版本Ø ˚F Ç ONTROL): -这是一个通用术语,并以多种方式(事件,委托等)来实现。

DId ependency njection): - DI是一个子类型的IoC并且通过实现构造函数注入,setter注入或接口注入

但是,Spring仅支持以下两种类型:

  • 二传手注射
    • 通过调用无参数构造函数或无参数静态工厂方法实例化其bean之后,在用户的bean上调用setter方法,可以实现基于setter的DI。
  • 构造函数注入
    • 基于构造函数的DI是通过调用带有多个参数(每个参数代表一个协作者)的构造函数来实现的,使用此参数,我们可以验证注入的bean不是null并快速失败(在编译时而不是在运行时失败),因此在启动应用程序本身时,我们得到了NullPointerException: bean does not exist。构造函数注入是注入依赖项的最佳实践。

1
指出Spring不支持属性注入是不正确的。是的 我同意,这是一种不良做法。
kekko12

我认为Spring @Autowired注释是一种属性注入的方法
Sajith

49

DI是IoC的子集

  • IoC意味着对象不会创建它们依靠其进行工作的其他对象。相反,他们从外部服务(例如xml文件或单个应用程序服务)获取所需的对象。我使用的2个IoC实现是DI和ServiceLocator。
  • DI表示获取依赖对象的IoC原理无需使用具体对象,而可以使用抽象(接口)。这使得所有组件都可以进行链测试,从而导致更高级别的组件不依赖于更低级别的组件,而仅依赖于接口。模拟实现这些接口。

这是实现IoC的其他一些技术


我不会说IoC意味着不创建对象。当您不是直接调用类方法而是接口方法时,这是控制的倒置(在这种情况下,调用者不依赖于调用代码),并且它与对象创建完全无关。IoC的另一个示例是事件和代表
Eugene Gorbovoy,

19

由于所有答案都强调理论,因此我想以第一种示例方式进行演示:

假设我们正在构建一个应用程序,其中包含一个功能,该功能可在订单发货后发送SMS确认消息。我们将有两个类,一个类负责发送SMS(SMSService),另一类负责捕获用户输入(UIHandler),我们的代码如下所示:

public class SMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
    }
}

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        SMSService _SMSService = new SMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

上面的实现并没有错,但是有几个问题
:-)假设在开发环境中,您想保存发送到文本文件的SMS而不是使用SMS网关来实现;我们最终将(SMSService)的具体实现更改为另一种实现,在这种情况下,我们失去了灵活性,不得不重写代码。
-)我们最终将混合类的职责,我们的(UIHandler)永远不应该知道(SMSService)的具体实现,这应该在类之外使用“接口”完成。当实现此功能时,它将使我们能够通过将(SMSService)与另一个实现相同接口的模拟服务交换来更改系统的行为,该服务会将SMS保存到文本文件中,而不是发送到mobileNumber。

为了解决上述问题,我们使用将由我们的(SMSService)和新的(MockSMSService)实现的接口,基本上,新的接口(ISMSService)将公开与以下代码相同的两种服务的行为:

public interface ISMSService
{
    void SendSMS(string phoneNumber, string body);
}

然后,我们将更改我们的(SMSService)实现以实现(ISMSService)接口:

public class SMSService : ISMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
        Console.WriteLine("Sending SMS using gateway to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

现在,我们将能够使用相同的接口使用完全不同的实现来创建新的模拟服务(MockSMSService):

public class MockSMSService :ISMSService
{
    public void SendSMS(string phoneNumber, string body)
    {
        SaveSMSToFile(phoneNumber,body);
    }

    private void SaveSMSToFile(string mobileNumber, string body)
    {
        /*implementation for saving SMS to a file*/
        Console.WriteLine("Mocking SMS using file to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

此时,我们可以更改(UIHandler)中的代码,以轻松使用服务的具体实现(MockSMSService),如下所示:

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        ISMSService _SMSService = new MockSMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

我们已经在代码中实现了很大的灵活性并实现了关注点分离,但是仍然需要对代码库进行更改,才能在两个SMS服务之间进行切换。因此,我们需要实现依赖注入

为此,我们需要对(UIHandler)类构造函数进行更改以通过其传递依赖关系,这样做,使用(UIHandler)的代码可以确定要使用(ISMSService)的具体实现:

public class UIHandler
{
    private readonly ISMSService _SMSService;

    public UIHandler(ISMSService SMSService)
    {
        _SMSService = SMSService;
    }

    public void SendConfirmationMsg(string mobileNumber)
    {
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

现在,将与类(UIHandler)交谈的UI表单负责传递要使用的接口实现(ISMSService)。这意味着我们已经反转了控件,(UIHandler)不再负责决定使用哪个实现,调用代码执行。我们已经实现了控制反转原理,DI是其中的一种。

UI表单代码如下:

class Program
{
    static void Main(string[] args)
    {
        ISMSService _SMSService = new MockSMSService(); // dependency

        UIHandler _UIHandler = new UIHandler(_SMSService);
        _UIHandler.SendConfirmationMsg("96279544480");

        Console.ReadLine();
    }
}

很棒的解释
ZiviMagic

19

IOC(控制反转):将控制交给容器以获取对象的实例称为控制反转,这意味着您无需使用new运算符来创建对象,而是让容器为您完成。

DI(依赖关系注入):将属性注入对象的方法称为依赖关系注入

我们有三种类型的依赖注入

  1. 构造函数注入
  2. 二传手/ Getter注入
  3. 接口注入

Spring仅支持构造函数注入Setter / Getter注入


5

但是春天的文档说它们是相同的。

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction

在第一行中,“ IoC也称为依赖注入(DI) ”。


1
我想他们正在尝试解决的问题是,DI是IoC设计模式的一种非常广泛使用的风格,几乎可以将其称为IoC aka DI-除非文档中有明确的引用,否则建议是这样。
ha9u63ar 2015年

5
“ IoC也被称为依赖注入(DI)”……马fe!
MikeM '16

5

IoC-控制反转是一个通用术语,与语言无关,它实际上不是创建对象,而是描述以哪种方式创建对象。

DI-依赖注入是一个具体的术语,其中我们通过使用不同的注入技术在运行时提供对象的依赖。设置器注入,构造器注入或通过接口注入。


4

控制反转是一种设计范例,其目标是为应用程序的目标组件提供更多控制,使目标组件能够完成工作。
依赖注入是一种模式,用于创建其他对象依赖的对象实例,而在编译时不知道将使用哪个类来提供该功能。

有几种实现控制反转的基本技术。这些是:

  • 使用工厂模式
  • 使用服务定位器模式
  • 使用以下任何给定类型的依赖项注入:

    1)。构造函数注入
    2)。二传手注射
    3)。接口注入

4

DIIOC是两种设计模式,主要着眼于在组件之间提供松散耦合,或者只是一种将对象之间的常规依赖关系解耦以使对象彼此不紧密的方式。

通过以下示例,我试图解释这两个概念。

以前我们是这样写的

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

使用依赖注入,依赖注入器将处理对象的实例化

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

以上将控制交给其他实例(例如容器)进行实例化和注入的过程可以称为控制反转,而IOC容器为我们注入依赖项的过程可以称为依赖项注入。

IOC是将程序的控制流反转的原理:程序由程序员通过减少依赖于程序员开销来控制流,而不是由程序控制程序流,而将程序用于注入依赖项的过程称为DI

这两个概念协同工作,为我们提供了一种编写更灵活,可重用和封装的代码的方法,这使它们成为设计面向对象解决方案时的重要概念。

也推荐阅读。

什么是依赖注入?

您也可以在这里检查我的类似答案之一

控制反转和依赖注入之间的区别


3

控制反转是软件体系结构的通用设计原则,有助于创建易于维护的可重用的模块化软件框架。

这是一种设计原理,其中从通用编写的库或可重用代码中“接收”控制流。

为了更好地理解它,让我们看看在早期的编码中我们是如何编码的。在过程/传统语言中,业务逻辑通常控制应用程序的流程并“调用”通用或可重用的代码/功能。例如,在一个简单的Console应用程序中,我的控制流由程序的指令控制,其中可能包括对一些常规可重用函数的调用。

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

相反,在IoC中,框架是“调用”业务逻辑的可重用代码。

例如,在基于Windows的系统中,已经可以使用框架来创建UI元素,例如按钮,菜单,窗口和对话框。当我编写应用程序的业务逻辑时,框架的事件将调用我的业务逻辑代码(触发事件时),而不是相反。

尽管框架的代码不了解我的业务逻辑,但它仍然会知道如何调用我的代码。这可以通过事件/代理,回调等来实现。这里的流控制是“反向的”。

因此,代替依赖静态绑定对象的控制流,该流依赖于整个对象图以及不同对象之间的关系。

依赖注入是一种实现IoC原理以解决对象依赖的设计模式。

简而言之,当您尝试编写代码时,将创建并使用不同的类。一个类别(A类)可以使用其他类别(B和/或D类)。因此,类B和D是类A的依赖项。

一个简单的类比将是Class Car。汽车可能取决于其他类别,例如引擎,轮胎等。

依赖注入建议,与其创建依赖关系(类引擎和轮胎类)的依赖类(此处为Class Car),不如使用依赖的具体实例注入类。

让我们用一个更实际的例子来理解。考虑您正在编写自己的TextEditor。除其他外,您可以使用拼写检查器,该工具为用户提供了一种检查其文字输入错误的工具。这种代码的简单实现可以是:

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

乍一看,一切看起来都很乐观。用户将写一些文本。开发人员将捕获文本并调用CheckSpellings函数,并将找到他将显示给用户的Typos列表。

一切顺利,直到一天下来,一个用户开始在编辑器中编写法语。

为了提供对更多语言的支持,我们需要更多的SpellChecker。可能是法语,德语,西班牙语等

在这里,我们创建了紧密耦合的代码,其中“ English” SpellChecker与TextEditor类紧密耦合,这意味着我们的TextEditor类依赖于EnglishSpellChecker,换句话说,EnglishSpellCheker是TextEditor的依赖项。我们需要删除此依赖性。此外,我们的文本编辑器需要一种方法,根据开发人员的判断,在运行时保存任何拼写检查器的具体参考。

因此,正如我们在DI的介绍中所看到的,它建议应在类中注入其依赖项。因此,将所有依赖项注入被调用的类/代码应该是调用代码的责任。因此我们可以将代码重组为

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

在我们的示例中,TextEditor类应接收ISpellChecker类型的具体实例。

现在,可以将依赖项注入到构造函数,公共属性或方法中。

让我们尝试使用构造函数DI更改类。更改后的TextEditor类将类似于:

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

这样,调用代码在创建文本编辑器时就可以将适当的SpellChecker类型注入到TextEditor的实例中。

您可以在此处阅读完整的文章


3

IOC(Inversion of Control):将控制权交给容器以获取对象的实例称为控制反转。这意味着您不必使用new运算符来创建对象,而是让容器为您完成。

DI(依赖注入):将所需的参数(属性)从XML传递到对象(在POJO CLASS中)称为依赖注入。


2

IOC指示外部类管理应用程序的类,而外部类表示容器管理应用程序类之间的依赖关系。IOC的基本概念是程序员不需要创建您的对象,而只需描述应如何创建它们。

IoC容器执行的主要任务是: 实例化应用程序类。配置对象。组装对象之间的依赖关系。

DI是通过使用setter注入或构造函数注入在运行时提供对象依赖项的过程。


2

IOC(控制反转)基本上是一种设计模式概念,它消除依赖关系并将它们解耦以使流程成为非线性流,并让容器/或其他实体管理依赖关系的提供。实际上,它遵循好莱坞负责人的“不要给我们打电话,我们会给您打电话”。因此,总结差异。

控制反转:-这是一个通用术语,用于解耦依赖关系并委托其供应,并且可以通过多种方式(事件,委托等)来实现。

依赖注入:-DI是IOC的子类型,通过构造函数注入,setter注入或方法注入实现。

下面的文章对此进行了非常简洁的描述。

https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO


1

我认为,无需陷入面向对象的杂草,就可以清楚地演示该想法,这似乎使该想法变得混乱。

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

如果您歪着头斜视眼睛,您会发现DI是IoC的一种特殊实现,具有特殊的问题。您不是将模型和行为注入到应用程序框架或高阶操作中,而是将变量注入到函数或对象中。


0

让我们从SOLID的D开始,并看一下Scott Millett的书“ Professional ASP.NET Design Patterns”中的DI和IoC:

依赖倒置原则(DIP)

DIP是所有关于从具体实现隔离你的类,并让他们依赖于抽象类或接口。它促进了对接口而不是实现的编码方式,通过确保您不紧密地与一个实现紧密耦合,从而增加了系统内的灵活性。

依赖注入(DI)和控制反转(IoC)

与DIP紧密相关的是DI原理和IoC原理。DI是通过构造函数,方法或属性提供低级或从属类的行为。与DI结合使用时,这些相关类可以转换为接口或抽象类,这将导致松散耦合的系统易于测试和更改。

IoC中,与过程编程相比,系统的控制流是相反的。一个示例是IoC容器,其目的是将服务注入到客户端代码中,而无需让客户端代码指定具体的实现。在这种情况下,被反转的控件是客户端获得服务的行为。

Millett,C(2010)。专业的ASP.NET设计模式。威利出版社。7-8。


0

// ICO,DI,十年前,这是他们的方式:

public class  AuditDAOImpl implements Audit{

    //dependency
    AuditDAO auditDAO = null;
        //Control of the AuditDAO is with AuditDAOImpl because its creating the object
    public AuditDAOImpl () {
        this.auditDAO = new AuditDAO ();
    }
}

现在是Spring 3,4或最新版本,如下所示

public class  AuditDAOImpl implements Audit{

    //dependency

     //Now control is shifted to Spring. Container find the object and provide it. 
    @Autowired
    AuditDAO auditDAO = null;

}

总体而言,控制权从耦合代码的旧概念转换为像Spring这样的框架,使对象可用。据我们所知,这就是IOC,而当我们使用Constructor或setter将依赖对象注入另一个对象时,就知道是依赖注入。基本上,注入意味着将其作为参数传递。在春季,我们有了基于XML和注释的配置,其中定义了bean对象,并以Constructor或setter注入样式传递了依赖对象。


0

我在Dzone.com上找到了最佳示例,这对理解IOC和DI的真正区别真的很有帮助

“ IoC是当您让其他人为您创建对象时。” 因此,无需在代码中编写“ new”关键字(例如,MyCode c = new MyCode()),而是由其他人创建对象。此“其他人”通常称为IoC容器。这意味着我们将rrsponsibility(control)移交给容器以获取对象的实例,称为Inversion of Control。,这意味着您无需使用new运算符来创建对象,而是让容器为您完成。

   DI(Dependency Injection):  Way of injecting properties to an object is 
   called 
  Dependency injection.
   We have three types of Dependency injection
    1)  Constructor Injection
    2)  Setter/Getter Injection
    3)  Interface Injection
   Spring will support only Constructor Injection and Setter/Getter Injection.

阅读全文IOC阅读全文DI


0

1)DI是Child-> obj取决于parent-obj。动词取决于很重要。2)IOC是Child-> obj在平台下执行的。平台可以是学校,大学,舞蹈课。在任何平台提供商的支持下,perform是一项具有不同含义的活动。

实际例子:

//DI
child.getSchool();
//IOC
child.perform()// is a stub implemented by dance-school
child.flourish()// is a stub implemented by dance-school/school/

`

-AB


0

关于这个问题,我想说Wiki已经提供了详细且易于理解的解释。我将在此引用最重要的内容。

实施IoC

在面向对象的编程中,有几种基本技术可以实现控制反转。这些是:

  1. 使用服务定位器模式使用依赖项注入,例如构造函数注入参数注入Setter注入接口注入;构造函数注入。
  2. 使用上下文查询;
  3. 采用模板法设计模式;
  4. 使用策略设计模式

至于依赖注入

依赖注入是一种技术,通过这种技术,一个对象(或静态方法)可以提供另一个对象的依赖关系。依赖项是可以使用的对象(服务)。注入是将依赖项传递给将使用它的依赖对象(客户端)。


0

IoC概念最初是在过程编程时代听到的。因此,IoC从历史的角度讨论控制所有权的倒置,即谁有责任按所需顺序调用功能-无论是功能本身还是应该将其转换为某个外部实体。

但是,一旦OOP出现,人们就开始在OOP上下文中谈论IoC,在这种情况下,应用程序除了控制流之外还关注对象的创建及其关系。这样的应用程序想要反转对象创建的所有权(而不是控制流),并且需要一个负责对象创建,对象生命周期和注入应用程序对象依赖关系的容器,从而消除了创建其他具体对象的应用程序对象。

从这个意义上说,DI与Io C不同,因为它与控制流无关,但是它是一种Io *,即对象创建所有权的倒置。

我解释DI和IoC的方式有什么问题?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.