美文网首页
IOC之依赖注入原理

IOC之依赖注入原理

作者: 做一只旅行青蛙 | 来源:发表于2021-09-10 18:43 被阅读0次

    IOC的一个很重要的实现就是依赖注入,将用户对类实例化的操作权,反转给容器去做,由容器来处理类与类之间的依赖关系,从而可以降低模块与模块之间的耦合关系。

    下面是手动实现的依赖注入原理:

    // es7的提案,ts1.5+版本已经支持,可以通过他给类或者类的原型属性上添加元数据
    import 'reflect-metadata';
     
    const INJECTED = '__inject__';
     
    type Constructor<T = any> = new (...args: any[]) => T;
     
    // 定义一个装饰器,他可以在类的构造函数上定义元数据,定义的元数据是构造函数的所有参数
    const Injectable = (): ClassDecorator => (constructor) => {
      Reflect.defineMetadata(
        INJECTED,
        Reflect.getMetadata('design:paramtypes', constructor), // 这里还支持两外两种内置元数据定义,一个是design:type获取属性类型,一个是design:returntype获取返回值类型
        constructor,
      );
    };
     
    @Injectable()
    class AService {
      a = 1;
    }
     
    @Injectable()
    class BService {
      b = 2;
      constructor(private aService: AService) {}
    }
     
    @Injectable()
    class TestService {
      constructor(
        private obj,
        private aService: AService,
        private bService: BService,
      ) {}
    }
     
    const getInstance = <T>(target: Constructor<T>): T => {
      // 获取所有注入的服务
      const providers = Reflect.getMetadata(INJECTED, target);
      const args =
        providers?.map((provider: Constructor) => {
          console.log(provider);
          return getInstance(provider); // 递归实例化所有依赖
        }) ?? [];
      return new target(...args);
    };
     
    console.log(getInstance(TestService));
     
    // 打印结果:
    /*
     *  [Function: Object]
     *  [class AService]
     *  [class BService]
     *  [class AService]
     *  TestService {
     *      obj: {},
     *      aService: AService { a: 1 },
     *      bService: BService { aService: AService { a: 1 }, b: 2 }
     *  }
    */
    

    特点:通过容器完成对象的装配,注入到需要的对象(被动获取)
    因此依赖注入又被称之为好莱坞原则:”Don't call us, we'll call you”,有事儿不要找我们,如果有需要我们会找你!

    相关文章

      网友评论

          本文标题:IOC之依赖注入原理

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