• 技术文章 >web前端 >js教程

    一起了解Angular中的依赖注入

    青灯夜游青灯夜游2021-02-22 17:55:56转载122
    本篇文章给大家介绍一下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重构后,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的依赖注入框架

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

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

    三、Injector

    本文转载自:https://www.cnblogs.com/starof/p/10506295.html

    更多编程相关知识,请访问:编程教学!!

    以上就是一起了解Angular中的依赖注入的详细内容,更多请关注php中文网其它相关文章!

    本文转载于:博客园,如有侵犯,请联系a@php.cn删除
    专题推荐:Angular 依赖注入
    上一篇:详解Angular中的路由守卫 下一篇:深入了解nodejs中的process对象
    第15期线上培训班

    相关文章推荐

    • angular脏值检测与vue数据劫持的区别是什么• 了解angularjs中的脏检查• Angular使用ngrx/store做状态管理• eclipse中如何配置angularjs插件的方法• 详解Angular中的路由守卫

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网