依赖注入(Dependency Injection)

翻译 2008年09月30日 20:35:00

 

Dependency injection

依赖注入

From Wikipedia, the free encyclopedia

Jump to: navigation, search

This article is about article is about the computing process. For other uses, see DI.

It has been suggested that Dependency inversion principle be merged into this article or section. (Discuss)

This article or section includes a list of references or external links, but its sources remain unclear because it lacks inline citations.

You can improve this article by introducing more precise citations where appropriate. (October 2007)

Dependency injection (DI) in Computer programming refers to the process of supplying an external dependency to a software component. It is a specific form of inversion of control where the concern being inverted is the process of obtaining the needed dependency.

计算机程序设计中的依赖注入(DI指的是将一个外部依赖项提供给一个软件组件的过程。这是一种特殊形式的控制反转,其中反转的关注点是获得需要的依赖项的处理。

 

Conventionally, if an object needs to gain access to a particular service, the object takes responsibility to get hold of that service: either it holds a direct reference to the location of that service, or it goes to a known 'service locator' and requests that it be passed back a reference to an implementation of a specified type of service. By contrast, using dependency injection, the object simply provides a property that can hold a reference to that type of service; and when the object is created a reference to an implementation of that type of service will automatically be injected into that property - by an external mechanism.

通常,如果一个对象要获得对某个特定服务的访问,对象自己将负责获得这个服务:要么此对象有对这个服务位置的直接引用,要么此对象向一个已知的‘服务定位器’发出请求以得到一个对于特定类型服务实现的引用。与之相对,使用依赖注入,对象只需要简单的提供一个类型,这个类型包含找到某种服务的引用,当对象被创建时,这个引用就可以被一个外部机制自动注入此对象的这个属性里.

 

When the dependency injection technique is used to decouple high-level modules from low-level services, the resulting design guideline is called the Dependency inversion principle.

在依赖注入技术开始被用于将高层模块与底层服务解耦的过程中,产生了被称为“依赖倒置原则”的设计准则

 

The dependency injection approach offers more flexibility because it becomes easier to create alternative implementations of a given service type, and then to specify which implementation is to be used via a configuration file, without any change to the objects that use the service. This is especially useful in unit testing, because it is easy to inject a mock implementation of a service into the object being tested. On the other hand, excessive use of dependency injection can make applications more complex and harder to maintain: in order to understand the application's behaviour the developer needs to look at the configuration as well as the code, and the configuration is "invisible" to IDE-supported reference analysis and refactoring unless the IDE specifically supports the dependency injection framework.

依赖注入使设计更加灵活。我们可以更容易创建给定服务类型的可选实现,并无需改动使用此服务的对象,仅通过配置文件就可以指定使用哪一个实现。由于可以非常容易的把一个模仿实现注入到被测试对象中,依赖注入技术在单元测试中非常有用。但是,过多的使用依赖注入将会令应用程序更加复杂而难于维护:为了理解应用程序的行为,除了阅读代码,开发人员还必须察看配置文件,然而,配置文件往往对于IDE提供的引用分析和重构机制不可见(除非IDE对依赖注入框架提供了特别的支持)。

Contents

目录

[hide]

A code illustration using Java

JAVA代码示例

 

Suppose that IFoo is an interface:

假设IFoo是一个接口

public interface IFoo
{
      void bar(); // Perform bar
      void baz(); // Perform baz
}

There exist also a number of implementation classes, each of them implementing IFoo in some way:

还有一些实现类,每一个都用不同方式实现了IFoo

public class DatabaseFoo
      implements IFoo
{
      void bar()
      {
          Database.selectBar().execute(); // Use the database to do bar
      }
 
      void baz()
      {
          Database.selectBaz().run(); // Use the database to do baz
      }
}

public class PixieDustFoo
      implements IFoo
{
      void bar()
      {
          Spell.cast("bar"); // Magic!
      }
 
      void baz()
      {
          Spell.cast("baz"); // Magic!
      }
}

public class EnterpriseFoo
      implements IFoo
{
      void bar()
      {
            EnterpriseFactoryObserverFactoryCreator efofc = new EnterpriseFactoryObserverFactoryCreator("bar");
            efofc.creatify();
            efofc.preparify();
            efofc.configurise();
            efofc.makeAwardWinning();
            efofc.opportunities.leverage();
      }
 
      void baz()
      {
            EnterpriseFactoryObserverFactoryCreator efofc = new EnterpriseFactoryObserverFactoryCreator("baz");
            efofc.creatify();
            efofc.preparify();
            efofc.configurise();
            efofc.makeAwardWinning();
            efofc.opportunities.leverage();
      }
}

IFoo only specifies the operations available in its interface, but doesn't itself provide any implementation, instead leaving that to other implementer classes. This way a user wishing to use the IFoo functionality can use any implementation, not knowing anything more about them than that they conform to the Foo interface.

IFoo仅仅指定了这个接口可以进行的操作,但并没有提供任何实现,而是留给了其它实现者的类。这样当一个用户希望使用IFoo功能,就可以使用任何一个实现,除了知道它们都遵守IFoo接口外,不需要事前知道任何更多的细节。

 

An object needing the services defined by IFoo needs to get an instance of a class that implements IFoo:

一个需要使用IFoo定义的服务的对象,需要得到一个实现IFoo的类的实例:

 

public class ImportantClass {
      IFoo foo;
 
      public ImportantClass()
      {
            this.foo = new EnterpriseFoo();
      }
 
      void doReallyImportantStuff()
      {
            this.foo.bar();
      }
}

However, this defeats the entire point of using an interface instead of a concrete implementation. To fix that, it's enough to let the outside caller provide the desired implementation:

但是,这完全破坏了使用接口而不是一个具体实现的目标。为修正这个问题,让外部调用者提供所需的实现就足可以满足目标了。

 

public ImportantClass(IFoo foo)
{
    this.foo = foo;
}

When using dependency injection there is usually a configuration mechanism or architecture for deciding which implementation gets injected into an object.

当使用依赖注入时,通常会有一个配置机制或是某个特定架构,以决定哪个实现将被注入到一个对象中。

 

Forms of Dependency Injection

依赖注入的几种形式

 

Martin Fowler identifies three ways in which an object can get a reference to an external module, according to the pattern used to provide the dependency:

依照提供依赖项时使用的模式,Martin Fowler定义了三种对象可以从得到一个外部模块引用的方式:

 

 

The open source Yan Container[1] provides support for arbitrary types of injection[2] besides the common ones defined above.

除了前列的几种普通形式外,开源项目Yan Container还对任意形式的注入提供了支持。

 

Existing frameworks

现有框架

 

Dependency injection frameworks exist for a number of platforms and languages including:

在一些平台和语言中都有依赖注入框架,包括:

ActionScript

C++

ColdFusion

Delphi

Java

Java 2 Micro Edition

.NET

PHP4

PHP5

Perl

Python

Ruby

See also

参见

 

External links

外部链接

Retrieved from "http://en.wikipedia.org/wiki/Dependency_injection"

Categories: Software components | Software architecture

Hidden categories: Articles to be merged since June 2008 | Articles lacking in-text citations | All articles with unsourced statements | Articles with unsourced statements since July 2008

 

源文档 <http://en.wikipedia.org/wiki/Dependency_injection>

 

AngularJs学习笔记--Dependency Injection(DI,依赖注入)

AngularJs学习笔记--Dependency Injection(DI,依赖注入) 原版地址:http://code.angularjs.org/1.0.2/docs/gu...
  • a460550542
  • a460550542
  • 2014年05月10日 12:17
  • 1024

JAVA的依赖注入模式(Dependency Injection Design Pattern in Java)

依赖注入模式可以使我们的代码是松耦合的、可扩展的及可维护性更高的。   依赖注入模式似乎是很难掌握和理解的,这里我用一个比较简单点的事例介绍下依赖注入模式。 比如我们有个EmailService...
  • xuesong830413
  • xuesong830413
  • 2014年03月21日 15:26
  • 1305

1.2.3依赖注入容器

【2017.12.30: 1.原博客 依赖注入(Dependency Injection)模式 大概的意思有,写得较垃圾:不流畅,例子不好。 2.不再将DI称为一种模式,而仅仅视为工具箱;强调 依...
  • yqj2065
  • yqj2065
  • 2013年01月16日 16:39
  • 24956

依赖注入&控制反转 oC 容器和Dependency Injection 模式

撰文/Martin Fowler 编译/透明Java 社群近来掀起了一阵轻量级容器的热潮,这些容器能够帮助开发者将来自不同项目的组件组装成为一个内聚的应用程序。在它们的背后有着同一个模式,这个模式决定...
  • suncheng_hong
  • suncheng_hong
  • 2006年11月09日 14:02
  • 4600

Scala中Dependency Injection

依赖注入是指 依赖对象的创建,由第三方完成,而不是被依赖对象,我们将这种控制关系的转移,称为依赖注入或者控制反转。在spring 的ioc 就是经典的案例。通过配置文件和反射机制,将依赖对象的创建交给...
  • pzw_0612
  • pzw_0612
  • 2015年07月19日 23:35
  • 1003

依赖注入(Dependency Injection)模式

1.2 依赖注入模式 依赖注入(Dependency Injection) 是一个非常简单的概念,伸手-等待。(让DIP、IoC滚蛋) 如例程1-5所示,Client依赖于抽象类型(甚...
  • CNHK1225
  • CNHK1225
  • 2015年12月17日 13:02
  • 644

前端框架Aurelia - 依赖注入Dependency Injection(一)

Let's say we have a CustomerEditScreen that needs to load a Customer entity by ID from a web servi...
  • oscar92420aaa
  • oscar92420aaa
  • 2017年03月22日 10:04
  • 335

依赖注入 理解Dependency Injection

依赖注入介绍on the wikiIn software engineering, dependency injection is a software design pattern that imp...
  • u014099894
  • u014099894
  • 2015年11月27日 10:49
  • 844

Inversion of Control(控制反转)之 Dependency Injection(依赖注入)

随着项目复杂度的提高,程序模块与模块间的关系犹如一碗意大利面。高耦合的代码会越来越难维护。所以松耦合的代码设计,会随着项目复杂度的提高而越来来越明显。GoF说过,依赖倒置原则:高层模块不应该依赖地层模...
  • hehehe12138
  • hehehe12138
  • 2016年03月03日 11:35
  • 562

【Scala】Cake模式和依赖注入

依赖注入(Dependency Injection)和控制反转(Inversion of Control)Dependency Injection & Inversion of Control是Mar...
  • JasonDing1354
  • JasonDing1354
  • 2016年03月11日 22:06
  • 2317
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:依赖注入(Dependency Injection)
举报原因:
原因补充:

(最多只允许输入30个字)