angular依赖注入_Angular依赖注入简介

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依赖注入

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值