1. 程式人生 > 程式設計 >詳解Angular依賴注入

詳解Angular依賴注入

概述

依賴注入:設計模式

依賴:程式裡需要的某種型別的物件。

依賴注入框架:工程化的框架

詳解Angular依賴注入

注入器Injector:用它的API建立依賴的例項

Provider:怎樣建立?(建構函式,工程函式)

Object:元件,模組需要的依賴

依賴性注入進階=>Angular中依賴注入框架提供父子層次注入型依賴

一、依賴注入

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街道");
  }
}

問題:Person需要清楚的知道Address和Id的實現細節。

ID和Address重構後,Pershttp://www.cppcns.comon需要知道怎麼重構。

專案規模擴大後,整合容易出問題。

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

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

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

main(){
WOGXlO
//把構造依賴物件,推到上一級,推呼叫的地方 const id = Id.getInstance("idcard"); const address = new Address("北京","xx街道"); const person = new Person(id,address); }

Person已經不知道Id和Address的細節了。

這是最簡單的依賴注入。

問題是在main裡還是需要知道細節。

思路:一級一級往上推,一直推到入口函式,入口函式來處理所有物件的構造。構造出來後提供給所有依賴的子模組的子類。

問題:入口函式很難維護。所以需要一個依賴注入框架幫助完成。

二、Angular的依賴注入框架

從v5開始,因為速度慢,引入大量程式碼已棄用,改為Injector.create。

ReflectiveInjector :用於例項化物件和解析依賴關係。import { Component,ReflectiveInjector } from "@angular/core";resolveAndCreate接收一個provider陣列,provider告訴injector應該怎樣去構造這個物件。

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相當於main函式,可以拿到所有依賴池子裡的東西。

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 {

www.cppcns.com  constructor(private oc: OverlayContainer) {
    //接收一個provider陣列
    const injector = ReflectiveInjector.resolveAndCreate([
      {
        provide: Person,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,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;
  }
}

可以看到控制檯打印出person資訊。

詳解Angular依賴注入

簡寫:

 // {
      //   provide: Person,useClass:Person
      // },Person,//簡寫為Person

在Angular框架中,框架做了很多事,在provider陣列中註冊的東西會自動註冊到池子中。

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

Angular預設都是單例,如果想要每次注入都是一個新的例項。有兩種方法。

一,return的時候return一個方法而不是物件。

{
    provide: Address,useFactory: ()=>{
        return ()=>{
            if(environment.production){
                return new Address("北京","xx街道xx號");
            }else{
                return new Address("西藏","xx街道xx號");
            }
        }
    }
},

二、利用父子Injector。

constructor(private oc: OverlayContainer) {
    //接收一個provider陣列
    c程式設計客棧onst injector = ReflectiveInjector.resolveAndCreate([
      Person,useFactory:()=>{
          return Id.getInstance('idcard');
        }
      }
    ]);

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

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

子注入器當中沒有找到依賴的時候會去父注入器中找

以上就是詳解Angular依賴注入的詳細內容,更多關於Angular的資料請關注我們其它相關文章!