de Neeraj Dana

În acest articol, vom vedea cum funcționează intern injecția de dependență a Angular. Să presupunem că avem o componentă numită appcomponent care are o structură de bază și simplă după cum urmează:

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 {      }}

Și avem o clasă de servicii numită GreetingService cu o funcție în ea sayHello care are un nume ca parametru și returnează numele cu „Hello” în fața sa.

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

Există două modalități de a utiliza clasa de servicii în componentă: în primul rând, putem crea manual o instanță a serviciului în componentă (aceasta este o cale greșită și nu este niciodată recomandată).

Și cealaltă modalitate este să lăsăm Angular să creeze instanța serviciului nostru și să transmită instanța respectivă componentei noastre intern. Acesta este modul comun și recomandat de a face acest lucru.

Injectarea serviciului nostru în sistemul de injecție de dependență angulară

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());  }}

Acum, dacă rulați acest proiect, veți primi eroarea „Niciun furnizor pentru GreetingService!”

O introducere in injectia de dependenta angulara

Deci, practic, Angular se plânge că nu a găsit niciun furnizor pentru crearea unei instanțe a serviciului de întâmpinare sau nu știe cum să creeze o instanță. Pentru a informa cadru despre cum ar trebui creată instanța, trebuie să transmitem un obiect furnizor proprietății furnizorilor în decoratorul de componente prezentat mai jos:

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());  }  }

În acest obiect furnizor, avem multe proprietăți, așa că permiteți-le să le înțelegem una câte una.

Fabrică personalizată

utilizați fabrica: aceasta va spune cadrului ce fabrică va fi utilizată la crearea obiectului serviciului. În cazul nostru, nu avem nicio fabrică, deci să creăm una.

Fabrica va fi o funcție care va fi responsabilă pentru crearea și returnarea obiectului serviciului.

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

Indicativ de injecție personalizat

Următorul lucru este să creați o proprietate a cărei valoare va fi o instanță de jeton de injecție. Folosind această proprietate, cadrul va identifica în mod unic serviciul nostru și va injecta instanța potrivită a serviciului.

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

Deci, în fragmentul de mai sus, creăm o instanță a clasei InjectionToken și este generică. În cazul nostru, instanța GreetingService va fi injectată atunci când cineva solicită injecția cu numele greetingToken.

Până în prezent, codul nostru va arăta astfel:

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";}

Dar, de asemenea, vom avea aceeași eroare:

1611485766 239 O introducere in injectia de dependenta angulara

Acest lucru se datorează faptului că în constructor, unde cerem instanța serviciului nostru, trebuie să-i spunem șirul unic al simbolului nostru de injecție care este greetingToken.

Deci, să ne actualizăm codul:

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

și acum vom avea rezultatul care ne permite să trecem cu succes un serviciu de la injecția de dependență angulară.

1611485766 931 O introducere in injectia de dependenta angulara

Acum, să presupunem că aveți câteva dependențe imbricate ca aceasta:

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

Deci, în acest caz, trebuie să mai transmitem o proprietate obiectului furnizorului (adică deps), care este matricea tuturor dependențelor:

@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";}

Până acum, orice am făcut a fost doar în scopuri de învățare. Nu este recomandat să creați furnizori manuali până când nu este nevoie.

Deci, aceasta este toată munca grea făcută de Angular în culise pentru noi. Nu trebuie să facem toate acestea pentru înregistrarea serviciului nostru. De fapt, putem reduce codul și, în loc să trecem manual din fabrică și jeton, putem cere cadrului să facă acest lucru pentru noi în acest caz.

Proprietatea de furnizare, care este jetonul de injecție, va fi numele serviciului, iar Angular va crea intern un jeton de injecție și o fabrică pentru noi.

Trebuie să trecem încă o proprietate (clasa de utilizare) care ne spune cadrului ce clasă trebuie să folosim:

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";}

Așadar, acum codul nostru arată mult mai curat și îl putem reduce și mai mult doar trecând numele serviciului. Apoi Angular sub capotă va crea obiectul de furnizare, fabrica și jetonul de injecție pentru noi și va pune instanța la dispoziția noastră atunci când este necesar.

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";}

Deci, în cele din urmă, codul nostru pare foarte familiar. Acum, în viitor, ori de câte ori creați un serviciu, știți exact ce pași sunt implicați pentru ca această instanță să fie disponibilă.

Dacă îți place acest articol, urmărește-mă pentru a obține mai multe lucruri de acest gen.

1611485766 153 O introducere in injectia de dependenta angulara

Vizita Smartcodehub