Angular 依赖性注入

依赖性注入
依赖性注入其实是一种设计模式,对应的还会有依赖性注入的框架,对于复杂的项目来说需要一个相对工程化的框架来帮我们处理这些事情,而angular就提供了一个比较完整的依赖性注入框架
这里写图片描述
这个框架当中有几个主要角色:
第一个:Injector 为注入者,你用这个注入者的api去创建你依赖的实例,但是怎么创建呢?是通过构造函数创建还是通过工厂方式还是其它方式,那就是Provider 它来告诉Injector如何来创建,最后创建好的这个对象其实就是你现在所处位置的组件或者模块所需要的依赖,这个依赖就是程序所需要的某种类型的对象
providor是用来告诉Injector应该怎么去构造一个对象

app.component.ts

import { environment } from '../environments/environment';
import { Component, ReflectiveInjector, Inject } from '@angular/core';

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

  constructor( @Inject('BASE_CONFIG') config) {
    console.log(config);
    //resolveAndCreate这个函数接受一个providor数组,根据这个数组来构建一个池子,这个池子可以提供给你依赖性,这个providor数组里面含有多个对象,对象中provide属性的值是一个令牌标识。其实这个池子干的事和我们刚开始定义的那个入口函数main()函数干的事一样,把应用要用到的依赖性全都放到这个池子里面,
    const injector = ReflectiveInjector.resolveAndCreate([
      { provide: Person, useClass: Person },
      {
        provide: Address, useFactory: () => { 
          // if (environment.production){
          //   return new Address('北京','北京','朝阳','xxx街道');
          // } else {
          //   return new Address('广东', '深圳', '南山', 'xx街道');
          // }

          //如果想每次返回的是不同的实例,而不是原来在池子里放的那个实例,而是你要给我创建一个新的,此时我们就可以return一个方法,而不是上面的那种返回方式。这是其中的一个方法,还可以通过父子
          return () => {
            if (environment.production) {
              return new Address('北京', '北京', '朝阳', 'xxx街道');
            } else {
              return new Address('广东', '深圳', '南山', 'xx街道');
            }
          }
        }
      },
      {
        provide: Id, useFactory: () => { 
          return Id.getInstance('idcard');
      }}
    ]);

    const childInjector = injector.resolveAndCreateChild([
      Person
    ]);
    const personFromChild = childInjector.get(Person);
    console.log(personFromChild);
   //通过injector.get()方法得到我的一个Person对象
    const person = injector.get(Person);
    console.log(person);

    console.log(person===personFromChild);
  }
  swichTheme(dark) {
    this.darkTheme = dark.checked;
  }
}

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

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

class Person {
  id: Id;
  address: Address;
  //@Inject(Id) id,@Inject(Address) address是什么 意思呢?就是说我现在需要两个依赖性,一个是Id 一个是Address,你分别到那个池子里去找
  constructor(@Inject(Id) id,@Inject(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);
// }

core.module.ts


//这里特殊引入了SkipSelf,
import { NgModule, SkipSelf ,Optional} from '@angular/core';
import { HttpModule } from "@angular/http";
import { DomSanitizer } from '@angular/platform-browser';
import { MdIconRegistry } from "@angular/material";
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SharedModule} from "../shared/shared.module";
import { HeaderComponent } from './header/header.component';
import { FooterComponent } from './footer/footer.component';
import { SidebarComponent } from './sidebar/sidebar.component';
import { loadSvgResources } from "../utils/svg.util";

@NgModule({
  imports: [
    HttpModule,
    BrowserAnimationsModule,
    SharedModule
  ],
  declarations: [
    HeaderComponent,
    FooterComponent,
    SidebarComponent
  ],
  exports: [
    HeaderComponent,
    FooterComponent,
    SidebarComponent
  ],
  //需要注意的一点是,在默认的情况下,这种依赖性的注入,angular是把它当做单件来处理的,也就是说一旦你把它放到池子里,它就变成一个单件了,大家取的都是那一个对象,都是那一个实例,如果。。。见app.component.ts
  providers: [
    {provide:'BASE_CONFIG',useValue:'http://localhost:3000'}
  ]
})
export class CoreModule {

  //@SkipSelf()这个注解是告诉说不要在我这里打转转了,去系统我的父级去寻找我的依赖,如果我已经存在了,那么在我的父亲的依赖池里面就会有我了,你去那里面找我,这样就可以避免无限循环了

  //第一次进入的时候,系统当中并没有CoreModule,所以用@Optional()告诉说这个依赖是可选的,当CoreModule不存在时,那就正常运行构造就好了。当存在时,那抛出一个异常就好了
  constructor( @Optional() @SkipSelf() parent: CoreModule,
    ir: MdIconRegistry,
    ds: DomSanitizer) {
    if (parent){
      throw new Error('模块已经存在,不能再次加载');
    }
    loadSvgResources(ir,ds);
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值