angular依赖注入

by Neeraj Dana

由Neeraj Dana

In this article, we will see how the dependency injection of Angular works internally. Suppose we have a component named appcomponent which has a basic and simple structure as follows:

在本文中,我们将看到Angular的依赖项注入在内部如何工作。 假设我们有一个名为appcomponent的组件,它具有如下基本且简单的结构:

import { Component, OnInit } from "@angular/core";@Component({  selector: "my-root",  templateUrl: "app.component.html",  styleUrls: ["app.component.css"]})export class AppComponent implements OnInit {  ngOnInit(): void {      }}

And we have a service class named GreetingService with a function in it sayHello which has a name as a parameter and returns the name with “Hello” in front of it.

我们有一个名为GreetingService的服务类,其中带有一个函数sayHello ,该函数具有一个名称作为参数,并在其前面返回名称为“ Hello”的名称。

export class GreetingService{  sayHello(name){    return `Hello ${name}` ;  }}

There are two ways to use the service class in the component: first, we can manually create an instance of the service in the component (this is the wrong way and is never recommended).

在组件中使用服务类的方式有两种:首先,我们可以在组件中手动创建服务的实例(这是错误的方式,从不推荐)。

And the other way is to let Angular create the instance of our service and pass that instance to our component internally. This is the common and recommended way to do it.

另一种方法是让Angular创建服务实例并将该实例内部传递给我们的组件。 这是常用的推荐方法。

将我们的服务注入Angular依赖注入系统 (Injecting our service in the Angular dependency injection system)

Import {Component} from '@angular/core';Import {GreetingService} from '. /greetingService';
@Component({  selector: 'my-app',  templateUrl: './app.component.html',  styleUrls: [ './app.component.css' ]})export class AppComponent  {
constructor(private greetingService : GreetingService){   console.log(this.greetingService.sayHello());  }}

Now if you run this project, you will get the error “No provider for GreetingService!”

现在,如果您运行此项目,您将收到错误“ No GreetingService没有提供者!”。

So, basically Angular is complaining that it did not find any provider for creating an instance of the greeting service or it does not know how to create an instance. In order to let the framework know how the instance should be created, we have to pass a provider object to the providers property in the component decorator shown below:

因此,基本上Angular抱怨它没有找到任何创建问候服务实例的提供程序,或者它不知道如何创建实例。 为了让框架知道如何创建实例,我们必须将提供程序对象传递给组件装饰器中的providers属性,如下所示:

import { Component } from '@angular/core';import {GreetingService} from './greetingService';
@Component({  selector: 'my-app',  templateUrl: './app.component.html',  styleUrls: [ './app.component.css' ],  providers:[{      }]})export class AppComponent  {
constructor(private greetingService : GreetingService){   console.log(this.greetingService.sayHello());  }  }

In this provider object, we have many properties so let us understand them one by one.

在此提供程序对象中,我们有许多属性,因此让我们一一理解它们。

定制工厂 (Custom Factory)

use factory: this will tell the framework which factory will be used while creating the object of the service. In our case, we don’t have any factory so let’s create one.

使用工厂:这将告诉框架在创建服务对象时将使用哪个工厂。 在我们的案例中,我们没有任何工厂,因此让我们创建一个工厂。

The factory will be a function which will be responsible for creating and returning the object of the service.

工厂将是一个负责创建和返回服务对象的功能。

export function greetingFactory(){   return  new GreetingService()};
Or more short way
export const greetingFactory= () =>  new GreetingService ();

自定义注入令牌 (Custom Injection Token)

The next thing is to create a property whose value will be an Injection Token instance. Using this property, the framework will uniquely identify our service and will inject the right instance of the service.

接下来的事情是创建一个属性,其值将是“注入令牌”实例。 使用此属性,框架将唯一地标识我们的服务,并将注入正确的服务实例。

var greetingTokken = new InjectionToken<GreetingService>("GREET_TOKEN");

So in the above snippet, we are creating an instance of the InjectionToken class and it is generic. In our case, the GreetingService instance will be injected when someone asks for the injection with name greetingToken.

因此,在上面的代码段中,我们正在创建InjectionToken类的实例,并且它是通用的。 在我们的示例中,当有人要求使用名称greetingToken进行注入时,将注入GreetingService实例。

So far now our code will look like this:

到目前为止,我们的代码将如下所示:

import { Component ,InjectionToken} from '@angular/core';import {GreetingService} from './greetingService';
export const greetingTokken = new InjectionToken<GreetingService>("GREET_TOKEN");export const greetingFactory=()=>  new GreetingService();@Component({  selector: 'my-app',  templateUrl: './app.component.html',  styleUrls: [ './app.component.css' ],  providers:[{    provide  : greetingTokken,    useFactory : greetingFactory,     }]})export class AppComponent  {
constructor(private greetingService : GreetingService){   console.log(this.greetingService.sayHello());  }  name = 'Angular';}

But then also we will have the same error:

但是然后我们也会有同样的错误:

This is because in the constructor, where we are asking for the instance of our service, we have to tell it the unique string of our injection token that is greetingToken.

这是因为在构造函数中,我们在其中请求服务实例时,必须告诉它注入令牌的唯一字符串,即greetingToken

So let’s update our code:

因此,让我们更新代码:

export class AppComponent  {
constructor(@Inject(greetingTokken) private greetingService : GreetingService){   console.log(this.greetingService.sayHello('Neeraj'));  }  name = 'Angular';}

and now we will have the result that allows us to successfully pass a service from Angular dependency injection.

现在,我们将获得的结果使我们能够成功地通过Angular依赖项注入传递服务。

Now let us assume you have some nested dependencies like this:

现在让我们假设您有一些嵌套的依赖项,如下所示:

import{DomSanitizer} from '@angular/platform-browser';
export class GreetingService{  constructor (private domSanitizer:DomSanitizer){      }  sayHello(name){    return `Hello ${name}`  }}

So, in this case, we have to pass one more property to the provider’s object (that is deps) which is the array of all the dependencies:

因此,在这种情况下,我们必须再传递一个属性到提供者的对象(即deps),该对象是所有依赖项的数组:

@Component({  selector: 'my-app',  templateUrl: './app.component.html',  styleUrls: [ './app.component.css' ],  providers:[{    provide  : greetingTokken,    useFactory : greetingFactory,    deps:[DomSanitizer]     }]})export class AppComponent  {
constructor(@Inject(greetingTokken) private greetingService : GreetingService  ){   console.log(this.greetingService.sayHello('Neeraj'));  }  name = 'Angular';}

Up until now, whatever we have done has only been for learning purposes. It is not recommended to create manual providers until there is a need.

到目前为止,我们所做的一切仅是出于学习目的。 不建议在需要之前创建手动提供程序。

So this is all the hard work done by Angular behind the scenes for us. We don’t have to do all this for registering our service. We can actually reduce the code, and instead of passing the factory and token manually, we can ask the framework to do this for us in that case.

因此,这就是Angular在后台为我们完成的所有艰苦工作。 我们不必为注册我们的服务而做所有这一切。 实际上,我们可以减少代码,而不是手动传递工厂和令牌,在这种情况下,我们可以要求框架为我们这样做。

The provide property, which is the injection token, will be the name of the service and Angular will internally create an injection token and factory for us.

提供属性(即注入令牌)将是服务的名称,Angular将在内部为我们创建注入令牌和工厂。

We have to pass one more property (use-class) which tells the framework which class we need to use:

我们必须再传递一个属性(使用类),该属性告诉框架我们需要使用哪个类:

import { Component ,InjectionToken,Inject} from '@angular/core';
import {GreetingService} from './greetingService';
@Component({  selector: 'my-app',  templateUrl: './app.component.html',  styleUrls: [ './app.component.css' ],  providers:[{    provide  : GreetingService,    useClass :GreetingService     }]})export class AppComponent  {
constructor( private greetingService : GreetingService  ){   console.log(this.greetingService.sayHello('Neeraj'));  }  name = 'Angular';}

So now our code looks much cleaner and we can further reduce it by just passing the name of the service. Then Angular under the hood will create the provide object, the factory, and the injection token for us and make the instance available to us when needed.

因此,现在我们的代码看起来更简洁了,我们可以通过传递服务名称来进一步减少代码。 然后,Angular在幕后将为我们创建提供对象,工厂和注入令牌,并在需要时使实例可用。

import { Component } from '@angular/core';
import {GreetingService} from './greetingService';
@Component({  selector: 'my-app',  templateUrl: './app.component.html',  styleUrls: [ './app.component.css' ],  providers:[GreetingService]})export class AppComponent  {
constructor( private greetingService : GreetingService  ){   console.log(this.greetingService.sayHello('Neeraj'));  }  name = 'Angular';}

So in the end, our code looks very familiar. Now in the future, whenever you create a service, you know exactly what steps are involved to get that instance available.

因此,最后,我们的代码看起来非常熟悉。 将来,无论何时创建服务,您都确切知道要使该实例可用需要执行哪些步骤。

If you like this article follow me to get more of this kind of stuff.

如果您喜欢本文,请跟随我获得更多此类内容。

Visit Smartcodehub

前往Smartcodehub

翻译自: https://www.freecodecamp.org/news/angular-dependency-injection-in-detail-8b6822d6457c/

angular依赖注入

angular依赖注入_Angular依赖注入简介相关推荐

  1. angular 注入器配置_Angular依赖注入介绍

    依赖注入(DI -- Dependency Injection)是一种重要的应用设计模式.Angular里面也有自己的DI框架,在设计应用时经常会用到它,它可以我们的开发效率和模块化程度. 依赖,是当 ...

  2. angular 注入器配置_angular依赖注入

    一.imports,declarations,providers介绍 imports中写入的是当前模块导入的其他模块,故imports应该导入的是module:declarations中写入的是当前模 ...

  3. 框架依赖注入和普通依赖注入_依赖注入快速入门:它是什么,以及何时使用它...

    框架依赖注入和普通依赖注入 by Bhavya Karia 通过Bhavya Karia 介绍 (Introduction) In software engineering, dependency i ...

  4. java依赖注入_Java依赖注入选项

    java依赖注入 我想花一些时间来总结一些流行的Java依赖注入(DI)框架. 这是可用功能的高级概述. 首先,什么是依赖注入? "依赖注入是一种软件设计模式,可以删除硬编码的依赖,并可以在 ...

  5. 依赖注入?依赖注入是如何实现解耦的?

    如何用最简单的方式解释依赖注入?依赖注入是如何实现解耦的? 第一章:小明和他的手机 从前有个人叫小明 小明有三大爱好,抽烟,喝酒-- 咳咳,不好意思,走错片场了.应该是逛知乎.玩王者农药和抢微信红包 ...

  6. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 创建 事件监听器 对应的 动态代理 | 动态代理的数据准备 | 创建调用处理程序 | 创建动态代理实例对象 )

    文章目录 前言 一.创建 事件监听器 对应的 动态代理 二.动态代理 数据准备 三.动态代理 调用处理程序 四.动态代理 实例对象创建 前言 Android 依赖注入的核心就是通过反射获取 类 / 方 ...

  7. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取要注入事件的 View 对象 | 通过反射获取 View 组件的事件设置方法 )

    文章目录 前言 一.获取要注入事件的 View 对象 二.通过反射获取 View 组件的事件设置方法并执行 前言 Android 依赖注入的核心就是通过反射获取 类 / 方法 / 字段 上的注解 , ...

  8. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取 Activity 中的所有方法 | 获取方法上的注解 | 获取注解上的注解 | 通过注解属性获取事件信息 )

    文章目录 前言 一.获取 Activity 中的所有方法 二.获取方法上的注解 三.获取注解上的注解 四.通过注解属性获取相关事件信息 前言 Android 依赖注入的核心就是通过反射获取 类 / 方 ...

  9. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入代码示例 )

    文章目录 总结 一.Android 事件依赖注入示例 1.创建依赖注入库 2.声明注解 (1).修饰注解的注解 (2).修饰方法的注解 3.Activity 基类 4.动态代理类调用处理程序 5.依赖 ...

最新文章

  1. 自己动手写C语言编译器(5)
  2. android OkHttp form 上传图片和参数
  3. 线上集群服务器性能参数查看命令
  4. php接收键盘事件,js获取键盘事件的方法实例
  5. python --- 线程
  6. python:__new__()与__init__()
  7. Oracle传输表空间介绍
  8. 游戏计算获胜概率_伟大的命令行挑战赛的获胜者宣布
  9. Google Reader 使用技巧及OPML订阅源分享
  10. 快速了解FTTx/FTTC/FTTB/FTTH
  11. linux下声卡配置文件,Linux设备配置之声卡配置
  12. c语言判断算符优先级,C语言算符优先级(精华)
  13. python用input输入整数列表_python中,用input()输入一个整数
  14. 文件共享服务器如何提高网速,局域网共享文件传输速度很慢怎么办
  15. wp8.1 java_巨硬的内部比较——WP8.1版本与WP10系统对比(以lumia640为例)
  16. 1-2 实验2 点对点通信
  17. win7与VMware/VBox下linux共享文件夹方法
  18. 51CTO乌镇行 追求“小轩窗,正梳妆”的宁静
  19. 数字地、模拟地、信号地区分
  20. 协议森林05 我尽力 (IP协议详解)

热门文章

  1. loj2245 [NOI2014]魔法森林 LCT
  2. 667. Beautiful Arrangement II
  3. 计算机科学速成课36:自然语言处理
  4. 8597 石子划分问题 dpdp,只考虑第一次即可
  5. spring boot中 使用http请求
  6. 代码扫描工具测试覆盖率工具
  7. ConTeXt 标题前后的空白
  8. ESFramework介绍之(23)―― AgileTcp
  9. unity5.4.3p2里面的AssetBundle打包流程
  10. SpringBoot + MyBatis(注解版),常用的SQL方法