Home  >  Article  >  Web Front-end  >  Let’s learn about dependency injection in Angular

Let’s learn about dependency injection in Angular

青灯夜游
青灯夜游forward
2021-02-19 17:56:581479browse

This article will introduce you to dependency injection in Angular. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.

Let’s learn about dependency injection in Angular

Related recommendations: "angular tutorial"

Dependency injection: design pattern

Dependencies: required in the program The object of some type.

Dependency Injection Framework: Engineering Framework

Injector: Use its API to create instances of dependencies

Provider: How create? (Constructor, engineering function)

Object: dependencies required by components and modules

Advanced dependency injection=>The dependency injection framework in Angular provides parent-child hierarchical injection Type dependency

1. Dependency injection

class Id {
  static getInstance(type: string): Id {
    return new Id();
  }
}

class Address {
  constructor(provice, city, district, street) {}
}

class Person {
  id: Id;
  address: Address;
  constructor() {
    this.id = Id.getInstance("idcard");
    this.address = new Address("北京", "背景", "朝阳区", "xx街道");
  }
}

Problem: Person needs to clearly know the implementation details of Address and Id.

After the ID and Address are reconstructed, Person needs to know how to reconstruct them.

After the scale of the project is expanded, integration problems are prone to occur.

class Id {
  static getInstance(type: string): Id {
    return new Id();
  }
}

class Address {
  constructor(provice, city, district, street) {}
}

class Person {
  id: Id;
  address: Address;
  constructor(id: Id, address: Address) {
    this.id = id;
    this.address = address;
  }
}

main(){
  //把构造依赖对象,推到上一级,推调用的地方
  const id = Id.getInstance("idcard");
  const address = new Address("北京", "背景", "朝阳区", "xx街道");
  const person = new Person(id , address);
}

Person no longer knows the details of Id and Address.

This is the simplest dependency injection.

Is the problem in main or I need to know the details.

Idea: Push up one level at a time, all the way to the entry function, which handles the construction of all objects. A subclass that is constructed and provided to all dependent submodules.

Problem: Entry functions are difficult to maintain. So a dependency injection framework is needed to help complete this.

2. Angular’s ​​dependency injection framework

Starting from v5, it has been deprecated due to its slow speed and the introduction of a large amount of code. Changed forInjector.create.

ReflectiveInjector : Used to instantiate objects and resolve dependencies.

import { Component ,ReflectiveInjector } from "@angular/core";

resolveAndCreate receives a provider array, and the provider tells the injector how to construct the object.

constructor() {
    //接收一个provider数组
    const injector = ReflectiveInjector.resolveAndCreate([
      {
        provide: Person, useClass:Person
      },
      {
        provide: Address, useFactory: ()=>{
          if(environment.production){
            return new Address("北京", "背景", "朝阳区", "xx街道xx号");
          }else{
            return new Address("西藏", "拉萨", "xx区", "xx街道xx号");
          }
        }
      },
      {
        provide: Id, useFactory:()=>{
          return Id.getInstance('idcard');
        }
      }
    ]);
  }

Injector:

injector is equivalent to the main function and can get all the things in the dependency pool.

import { Component ,ReflectiveInjector, Inject} from "@angular/core";
import { OverlayContainer } from "@angular/cdk/overlay";
import { Identifiers } from "@angular/compiler";
import { stagger } from "@angular/animations";
import { environment } from 'src/environments/environment';

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"]
})
export class AppComponent {

  constructor(private oc: OverlayContainer) {
    //接收一个provider数组
    const injector = ReflectiveInjector.resolveAndCreate([
      {
        provide: Person, useClass:Person
      },
      {
        provide: Address, useFactory: ()=>{
          if(environment.production){
            return new Address("北京", "背景", "朝阳区", "xx街道xx号");
          }else{
            return new Address("西藏", "拉萨", "xx区", "xx街道xx号");
          }
        }
      },
      {
        provide: Id, useFactory:()=>{
          return Id.getInstance('idcard');
        }
      }
    ]);
    const person = injector.get(Person);
    console.log(JSON.stringify(person));
  }

}

class Id {
  static getInstance(type: string): Id {
    return new Id();
  }
}

class Address {
  provice:string;
  city:string;
  district:string;
  street:string;
  constructor(provice, city, district, street) {
    this.provice=provice;
    this.city=city;
    this.district=district;
    this.street=street;
  }
}

class Person {
  id: Id;
  address: Address;
  constructor(@Inject(Id) id, @Inject(Address )address) {
    this.id = id;
    this.address = address;
  }
}

You can see the person information printed out on the console.

##Abbreviation:

      // {
      //   provide: Person, useClass:Person
      // },
      Person, //简写为Person

In the Angular framework, the framework does a lot of things. Things registered in the provider array will automatically be registered in the pool.

@NgModule({
  imports: [HttpClientModule, SharedModule, AppRoutingModule, BrowserAnimationsModule],
  declarations: [components],
  exports: [components, AppRoutingModule, BrowserAnimationsModule],
  providers:[
    {provide:'BASE_CONFIG',useValue:'http://localhost:3000'}
  ]
})
  constructor( @Inject('BASE_CONFIG') config) {
    console.log(config);  //控制台打印出http://localhost:3000
  }

Angular is a singleton by default. If you want to inject a new instance every time. There are two ways.

First, when returning, return a method instead of an object.

{
        provide: Address, useFactory: ()=>{
          return ()=>{
            if(environment.production){
              return new Address("北京", "背景", "朝阳区", "xx街道xx号");
            }else{
              return new Address("西藏", "拉萨", "xx区", "xx街道xx号");
            }
          }
        }
      },

2. Use the father-son Injector.

constructor(private oc: OverlayContainer) {
    //接收一个provider数组
    const injector = ReflectiveInjector.resolveAndCreate([
      Person,
      {
        provide: Address, useFactory: ()=>{
          if(environment.production){
            return new Address("北京", "背景", "朝阳区", "xx街道xx号");
          }else{
            return new Address("西藏", "拉萨", "xx区", "xx街道xx号");
          }
        }
      },
      {
        provide: Id, useFactory:()=>{
          return Id.getInstance('idcard');
        }
      }
    ]);

    const childInjector = injector.resolveAndCreateChild([Person]);

    const person = injector.get(Person);
    console.log(JSON.stringify(person));
    const personFromChild = childInjector.get(Person);
    console.log(person===personFromChild);  //false
  }

When the dependency is not found in the child injector, it will look for it in the parent injector.

3. Injector

This article is reproduced from: https://www.cnblogs.com/starof/p/10506295.html


For more programming-related knowledge, please visit:

Programming Teaching! !

The above is the detailed content of Let’s learn about dependency injection in Angular. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:cnblogs.com. If there is any infringement, please contact admin@php.cn delete