美文网首页Angular框架专题
Angular框架中的Provider依赖注入(DI)

Angular框架中的Provider依赖注入(DI)

作者: 听书先生 | 来源:发表于2021-12-13 22:43 被阅读0次

    依赖注入是Angular的核心,在设计应用的时候会使用到,它可以帮助我们提高开发效率和模块化程度,DI是一种编码模式,其中的类会从外部源中请求获取依赖,而不需要我们去创建它们,Angular系统中通过在类上添加@Injectable装饰器来告诉系统这个类(服务)是可注入的。

    1、使用Provider来描述与Token关联的依赖对象的创建方式

    Angular中依赖对象的创建方式共用4种:

    • 1、useClass
    • 2、useValue
    • 3、useExisting
    • 4、useFactory
    1.1、useClass:
    import {NgModule, APP_INITIALIZER, Injectable} from '@angular/core';
    import {BrowserModule, HammerGestureConfig, HAMMER_GESTURE_CONFIG} from '@angular/platform-browser';
    ...
    
    @Injectable()
    export class ApiService {
        constructor(
          public http: Http
        )      
    }
    
    @NgModule({
        declarations: [AppComponent],
        entryComponents: [],
        imports: [
            BrowserModule,
            ....
        ],
        providers: [
            ....
            { provide: RouteReuseStrategy, useClass: ApiService }
        ],
        bootstrap: [AppComponent]
    })
    export class AppModule {
    }
    
    
    1.2、useValue:
      { provide: 'API_URL', useValue: 'http://api.com/v2' }
    
    1.3、useExisting:
      { provide: 'ApiServiceAlias', useExisting: ApiService }
    
    1.3、useFactory:
    export function configFactory(config: AppConfig) {
      return () => config.load();
    }
    
    @NgModule({
      ...
      providers: [
           { provide: APP_INITIALIZER, useFactory: configFactory, 
            deps: [AppConfig], multi: true }
      ]
    })
    export class CoreModule { }
    
    
    2、使用Provide

    使用Provide需要首先创建Token,Token的作用是用来标识依赖对象,Token值可能是Type、InjectionToken类的实例或者字符串。推荐使用InjectionToken.
    然后根据实际的需求选择依赖对象的创建方式,如:useClass、useValue、useExisting、useFactory等方式。
    接着在NgModule或者是Component中去注册providers
    最后使用构造注入的方式,注入与Token关联的依赖对象。

    /**
    * 封装Http服务,如在每个Http的请求头中添加token
    */
    @Injectable() 
    export class ApiService {
       constructor(
       // 调用Http服务后,返回Observable对象
          public http: Http) { 
       }
       ...
    }
    
    @NgModule({
      ...
      providers: [
           { provide: ApiService, useClass: ApiService } 
      ]
    })
    export class AppModule { }
    

    组件页面中去调起:

    export class HomePage {
      constructor(
        public apiService: ApiService // 使用构造注入的方式,注入ApiService的实例对象
      ) { }
      
      ngOnInit(): void {
        this.apiService.get(url) 
        .map(res => res.json()) // 返回的res对象是Response类型的实例
        .subscribe(result => {
          ...
        })
      }
    }
    

    当DI系统解析Providers时,都会对提供的每个provider进行规范化处理,也就是转换成标准的形式。

    function _normalizeProviders(providers: Provider[], res: Provider[]): Provider[] {
      providers.forEach(b => {
        if (b instanceof Type) { // 支持简洁的语法,转换为标准格式
          res.push({provide: b, useClass: b});
        } else if (b && typeof b == 'object' && (b as any).provide !== undefined) {
          res.push(b as NormalizedProvider);
        } else if (b instanceof Array) {
          _normalizeProviders(b, res); // 如果是数组,进行递归处理
        } else {
          throw invalidProviderError(b);
        }
      });
      return res;
    }
    
    

    (参考了网上一些angular的资料)

    相关文章

      网友评论

        本文标题:Angular框架中的Provider依赖注入(DI)

        本文链接:https://www.haomeiwen.com/subject/zqvsfrtx.html