Dependency Injection 依赖注入(官方原文翻译)

Dependency Injection (DI) is a software design pattern that deals with how components get hold of their dependencies.

依赖注入是一个软件设计规则 用来 解决:组件怎样得到他们的依赖

The Angular injector subsystem is in charge of creating components,resolving their dependencies,and providing them to other components as requested.

Angular 注入器 辅助系统 负责 创建组件,得到组件的依赖,提供组件自身到别的组件 ,当别的组件请求这些组件时。


Using Dependency Injection
DI is pervasive throughout Angular. You can use it when defining components or when providing runand configblocks for a module.

DI在Angular里是无处不在的。你可以在为一个模块 定义组件 或 规定run和config块的时候使用它。

  • Components such as services,directives,filters,and animations are defined by an injectable factory method or constructor function. These components can be injected with "service" and "value" components as dependencies.
    组件像 services,filters和 animations 都是通过可被注入的工厂函数或构造函数定义的。

  • Controllers are defined by a constructor function,which can be injected with any of the "service" and "value" components as dependencies,but they can also be provided with special dependencies. See Controllersbelow for a list of these special dependencies.
    controllers是通过构造函数定义的,可被注入'service'或'value'组件来作为依赖,但他们也可以作为特殊的依赖被提供。可通过点击蓝色链接来查看controllers作为特殊依赖的情况。

  • The runmethod accepts a function,which can be injected with "service","value" and "constant" components as dependencies. Note that you cannot inject "providers" into runblocks.
run方法接收一个函数,可以用来被注入'service','value','constant'组件作为依赖。
注意,你不能注入'providers'进run。

  • The config method accepts a function,which can be injected with "provider" and "constant" components as dependencies. Note that you cannot inject "service" or "value" components into configuration.
    config方法接收一个函数,用来被注入'provider'和'constant'组件作为依赖。注意,你不能注入'service'和'value'组件进入配置。

SeeModulesfor more details aboutrunandconfigblocks.

Factory Methods

The way you define a directive,service,or filter is with a factory function. The factory methods are registered with modules. The recommended way of declaring factories is:
定义directive,service或filter是通过一个工厂函数。工厂方法是注册在modules上。推荐声明工厂的方法是:
angular.module('myModule', []).factory('serviceId', ['depService', function(depService) { // ...}]).directive('directiveName',136)">// ...}]).filter('filterName',136)">// ...}]);

Module Methods

We can specify functions to run at configuration and run time for a module by calling the configand runmethods. These functions are injectable with dependencies just like the factory functions above.
我们可以指定运行的函数在配置阶段 和 run 的时候 通过调用module上的config和run方法。这些函数是可被注入依赖的,就像上面的工厂函数那样。
 []).config(['depProvider', function(depProvider) { // ...}]).run([ Controllers 
Controllers are "classes" or "constructor functions" that are responsible for providing the application behavior that supports the declarative markup in the template. The recommended way of declaring Controllers is using the array notation:
Controllers 是 "classes"或"constructor functions",负责提供应用的行为用来支持模板中的指令标签。推荐定义控制器的方法是使用array注释:
someModule.controller('MyController',68)">'$scope', 'dep1',68)">'dep2', function($scope, dep1, dep2) { ... $scope.aMethod = function() { ... } ...}]);
Unlike services,there can be many instances of the same type of controller in an application.
不像services,在一个应用中可以有很多同类controller的实例
Moreover,additional dependencies are made available to Controllers:
而且,追加的依赖 也可被Controllers获取。
  • $scope: Controllers are associated with an element in the DOM and so are provided with access to thescope. Other components (like services) only have access to the$rootScopeservice.
$scope: 控制器是和DOM中的一个元素关联的,所以能够访问$scope。其他组件(像services)只能访问$rootScope服务。
  • resolves: If a controller is instantiated as part of a route,then any values that are resolved as part of the route are made available for injection into the controller.
resolves: 如果一个controller 被作为route的一部分实例化,那么任何作为路由一部分得到的值 是可注入进controller的。

Dependency Annotation

Angular invokes certain functions (like service factories and controllers) via the injector. You need to annotate these functions so that the injector knows what services to inject into the function. There are three ways of annotating your code with service name information:
Angular 调用某些函数(像工厂类的service和controllers)通过 注入器。你需要给这些函数注释,这样注入器知道什么样的services要被注入到这个函数。这里有3个方法注释你的代码带上service的名字信息。
  • Using the inline array annotation (preferred)
使用行内数组注释(首选)
  • Using the$injectproperty annotation
使用$inject属性注释
  • Implicitly from the function parameter names (has caveats)
从函数参数中隐式注释

Inline Array Annotation(内联数组注释)
This is the preferred way to annotate application components. This is how the examples in the documentation are written.
这是首选的方法注释应用组件。下面是文档中的例子:

For example:

'greeter', greeter) { // ...}]);
Here we pass an array whose elements consist of a list of strings (the names of the dependencies) followed by the function itself.
这里我们传入一个数组,数组元素由字符串列表(依赖的名字)然后跟上被调用的函数。
When using this type of annotation,take care to keep the annotation array in sync with the parameters in the function declaration.
当使用这种类型的注释时,要注意保持注释数组和函数参数同步。

$injectProperty Annotation($inject属性注释)

To allow the minifiers to rename the function parameters and still be able to inject the right services,the function needs to be annotated with the $injectproperty. The $injectproperty is an array of service names to inject.
为了允许the minifiers 重命名函数参数,但仍能够注入正确的services,函数需要被注释$inject属性。$inject属性是一个包含需要被注入的service名字的数组。
var MyController = function($scope,136)">// ...}MyController.$inject = ['greeter']; someModule.controller( MyController);
In this scenario the ordering of the values in the $injectarray must match the ordering of the parameters in MyController.
在这个场景中,$inject数组中的值的顺序必须和被注释的函数参数的顺序匹配。
Just like with the array annotation,you'll need to take care to keep the $injectin sync with the parameters in the function declaration.
就像‘数组注释’,你需要注意保持$inject和函数声明中参数的同步。

Implicit Annotation(隐式注释)
Careful:If you plan to minifyyour code,your service names will get renamed and break your app.
注意:如果你计划精简你的代码,你的service名会被重命名,这样会破坏你的应用。

The simplest way to get hold of the dependencies is to assume that the function parameter names are the names of the dependencies.
获取依赖最简单的方法是假定函数参数名是这些依赖的名字。
// ...});
Given a function,the injector can infer the names of the services to inject by examining the function declaration and extracting the parameter names. In the above example,$scopeand greeterare two services which need to be injected into the function.
给定一个函数,注入器会通过检查函数声明并摘取参数名来推断services的名字来注入这些services。在上面的例子中,$scope和greeter是两个需要被注入到函数的services。
One advantage of this approach is that there's no array of names to keep in sync with the function parameters. You can also freely reorder dependencies.
这种方法的一个优势是不需要去关心 ‘包含名字的数组’和函数参数的同步问题。你可以不用关心依赖的顺序。
However this method will not work with JavaScript minifiers/obfuscators because of how they rename parameters.
无论如何不能够生效当使用JavaScript压缩器/ 因为他们会重命名参数。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


什么是设计模式一套被反复使用、多数人知晓的、经过分类编目的、代码 设计经验 的总结;使用设计模式是为了 可重用 代码、让代码 更容易 被他人理解、保证代码 可靠性;设计模式使代码编制  真正工程化;设计模式使软件工程的 基石脉络, 如同大厦的结构一样;并不直接用来完成代码的编写,而是 描述 在各种不同情况下,要怎么解决问题的一种方案;能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免引
单一职责原则定义(Single Responsibility Principle,SRP)一个对象应该只包含 单一的职责,并且该职责被完整地封装在一个类中。Every  Object should have  a single responsibility, and that responsibility should be entirely encapsulated by t
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强烈推荐。原文截图*************************************************************************************************************************原文文本************
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的一些设计问题,总结出来的一套通用的解决方案。
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
外观模式又叫门面模式,它提供了一个统一的(高层)接口,用来访问子系统中的一群接口,使得子系统更容易使用。
单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。
组合模式可以将对象组合成树形结构来表示“整体-部分”的层次结构,使得客户可以用一致的方式处理个别对象和对象组合。
装饰者模式能够更灵活的,动态的给对象添加其它功能,而不需要修改任何现有的底层代码。
观察者模式(Observer Design Pattern)定义了对象之间的一对多依赖,当对象状态改变的时候,所有依赖者都会自动收到通知。
代理模式为对象提供一个代理,来控制对该对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来给原始类附加功能。
工厂模式(Factory Design Pattern)可细分为三种,分别是简单工厂,工厂方法和抽象工厂,它们都是为了更好的创建对象。
状态模式允许对象在内部状态改变时,改变它的行为,对象看起来好像改变了它的类。
命令模式将请求封装为对象,能够支持请求的排队执行、记录日志、撤销等功能。
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 基本介绍 **意图:**在不破坏封装性的前提下,捕获一个对象的内部状态,并在该
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为
享元模式(Flyweight Pattern)(轻量级)(共享元素)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结