• Angular基础(六) DI


     

     

     

    一、依赖注入

    a) 如果模块A需要依赖模块B,通常的做法是在A中导入B,import{B} from ‘B’,但有一些场合需要解除这种直接依赖,比如单元测试时需要mock一个B对象、还有时要创建B的单例或者用工厂模式生成B,这时适合使用依赖注入(Dependency Injection)的方式来解除对B的直接依赖。

     

    b) Angular的依赖注入框架包含三部分,Provider、Injector、Dependency,三者的关系为:

    Provider的作用是建立类与其依赖项之间的映射(mapinding);Dependency为依赖项;Injector负责在创建对象的时候解析相关的依赖并根据Provider提供的绑定信息进行注入。

     

    c) 记录用户登录信息的UserService是一个全局单例,对其注入并使用的例子为:

    import{ Component, ReflectiveInjector } from '@angular/core';

    import{ UserService } from '../services/user.service';

    exportclass UserDemoComponent {

      userName: string;

      userService: UserService;

      constructor() {

        const injector: any =

    ReflectiveInjector.resolveAndCreate([UserService]);

        this.userService =injector.get(UserService);

      }

      signIn(): void {

        this.userService.setUser({ name: 'Dante'});

        this.userName =this.userService.getUser().name;

      }

    }

    导入ReflectiveInjector类后,使用它的静态方法resolveAndCreate来创建一个injector,可被注入的内容以数组的形式从参数传入,injector.get(UserService)可以解析出一个UserService对象,这里将类本身作为token。

     

    二、使用NgModule进行注入

    a) 通过前面的代码可以直观地了解注入的过程,但实际使用中却不这样做,而是要在NgModule的providers中注册依赖项,然后通过装饰器在需要使用的类的构造函数中注入:

    constructor(privateuserService: UserService) {}

    需要注意的是,被注入的类要用@Injectable标记,而且这样是以单例的方式注入的,还有其它注入的形式,比如非单例类、注入一个值、调用方法并把方法的返回值注入等。

    providers:[UserService]这样的写法默认会注入UserService的单例,这实际上是一种简化的写法,provider的完整配置代码应该为

    providers: [{ provide: UserService, useClass: UserService }],

    provide字段指明了注入时的token,通过userClassuseValue等则可以设置注入对象和注入方式。

    b) 注入值

    //配置

    providers:[{ provide: 'API_URL', useValue: 'http://api.com/v1' }]

    //使用

    import{ Inject } from '@angular/core';

    constructor(@Inject('API_URL')apiUrl: string) {}

    使用的时候要用到@Inject标记,使用这种写法可以注入全局常量。

     

    c) 调用方法

    {provide: 'API_URL', useFactory() { return 'api.com'; }

    使用useFactory来调用方法作为返回值,可以使用上面的写法,也可以使用lambda表达式的形式useFactory : ( )=>…

    useFactory指向的方法的返回值将会被注入。

    d) 如果调用的方法需要传入参数,可以使用第三个属性:deps,比如API_URL1要用到API_URL的值作为参数:

    {provide: 'API_URL1', deps: ['API_URL'], useFactory(apiUrl: string) { returnapiUrl + 'api.com'; }

    那么如果要注入非单例对象,也可以通过useFactory来实例化并返回了。

     

     

     

     

  • 相关阅读:
    Ubuntu下建立Android开发环境
    c#值类型和引用类型
    Jude Begin
    Eclipse C/C++ development environment creation
    C# var usage from MSDN
    SubSonic应用_Collection
    C#2.0中委托与匿名委托引
    sql语句的执行步骤——zhuan
    图˙谱˙马尔科夫过程·聚类结构 (转载,原始出处不详)
    Hadoop集群新增节点实现方案
  • 原文地址:https://www.cnblogs.com/zhixin9001/p/7420543.html
Copyright © 2020-2023  润新知