zoukankan      html  css  js  c++  java
  • Angular 依赖注入

    依赖注入:设计模式

    依赖:程序里需要的某种类型的对象。

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

    注入者Injector:用它的API创建依赖的实例

    Provider:怎样创建?(构造函数,工程函数)

    Object:组件,模块需要的依赖

    依赖性注入进阶=>父子层次依赖

    一、依赖注入

    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重构后,Person需要知道怎么重构。

    项目规模扩大后,集成容易出问题。

    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已经不知道Id和Address的细节了。

    这是最简单的依赖注入。

    问题是在main里还是需要知道细节。

    思路:一级一级往上推,一直推到入口函数,入口函数来处理所有对象的构造。构造出来后提供给所有依赖的子模块的子类。

    问题:入口函数很难维护。所以需要一个依赖注入框架帮助完成。

    二、Angular的依赖注入框架

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

    可以看到控制台打印出person信息。 

    简写:

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

    在Angular框架中,框架做了很多事,在provider数组中注册的东西会自动注册到池子中。

    @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默认都是单例,如果想要每次注入都是一个新的实例。有两种方法。

    一,return的时候return一个方法而不是对象。

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

    二、利用父子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
      }

    子注入者当中没有找到依赖的时候会去父注入者中找。

  • 相关阅读:
    HDU
    HDU
    POJ
    HDU
    HDU
    POJ
    HDU
    FZU
    LightOJ 1030 Discovering Gold 数学期望计算
    POJ 3061 Subsequence 二分查找
  • 原文地址:https://www.cnblogs.com/starof/p/10506295.html
Copyright © 2011-2022 走看看