角度反射注射器与注射器的区别

我试图用两种方式明确地创建依赖.两者几乎相同,但我有点混淆使用反射注射器优于普通注射器的优势是什么?推荐哪种方式?

使用注射器

import { Injector } from '@angular/core';
constructor( private injector: Injector) {
    this.myService = this.injector.get(MyService);
  }

使用反射注射器

import { ReflectiveInjector } from '@angular/core';
 constructor() {

       var injector= ReflectiveInjector.resolveAndCreate([MyService]);
       let myservice=injector.get(MyService);
     }
注入器是具有提供者/服务的容器.它实现了一个方法get并返回一个服务实例.让我们在JS伪代码中实现最基本的注入器版本:
class ReflectiveInjector {
   providers = [];

   static resolveAndCreate(providers) {
     providers.forEach((provider)=>{
         providers.push({token: provider.provide,instance: new provider.useClass})
     });  
  )}

  get(dep) {
     return providers.find((provider)=>{ return provider.token === token });
  }
}

现在,我们需要在使用它之前创建注入器的实例.当我们创建它时,我们定义提供者:

const existingInjector = ReflectiveInjector.resolveAndCreate([{provide: A,useClass: A }]);
const AInstance = existingInjector.get(A);

所以你看,为了使用注射器,必须首先创建它.它没有任何允许添加提供程序的特定方法,因此在创建之后我们无法向其添加任何新提供程序.

注入组件构造函数的注入器已由Angular创建.您无法向其添加任何内容,只能查询已在其上定义的提供程序.如果您需要提供B类,则不能使用现有的注射器.你需要一个新的.这就是ReflectiveInjector类的用武之地.它允许您通过创建注入器的新实例并注册新的提供程序来添加新的提供程序.而且好处是它还可以设置喷射器链.

让我们稍微修改resolveAndCreate并获取允许链接注入器的方法

class ReflectiveInjector {
   providers = [];
   parent;

   static resolveAndCreate(providers,parent) {
       this.parent = parent;
   ...
   }

   get(dep) {
       let found = providers.find((provider)=>{ return provider.token === token });
       if (!found && parent) {
            found = parent.get(dep);
       }

       return found;
   }

所以现在唯一剩下的就是使用它:

// passing existingInjector as a parent
const childInjector = ReflectiveInjector.resolveAndCreate([{provide: B,useClass: B }],i);
const AInstance = childInjector.get(A);
const BInstance = childInjector.get(B);

现在,假设有人可能想要访问我们现有的注入者.我们需要一个令牌来使用这个现有的注入器.让我们像这样定义这个标记

abstract class Injector {}

让我们编写一个能够获得现有注入器的函数

function resolveDependency(token) {
   if (token === Injector) {
       return existingInjector;
   }
}

现在假设Angular在执行组件的构造函数时,使用您指定的标记获取依赖项并将它们传递给resolveDependency函数.所以你这样写:

// the Injector here is a reference to our abstract Injector class and simply used as a token
MyComp {
   constructor(private injector: Injector) { ...  }
}

这里的令牌是Injector,正如我所说,它被传递到resolveDependency函数并返回现有的注入器.

相关文章

AngularJS 是一个JavaScript 框架。它可通过 注:建议把脚本放在 元素的底部。这会提高网页加载速度,因...
angluarjs中页面初始化的时候会出现语法{{}}在页面中问题,也即是页面闪烁问题。出现这个的原因是:由于...
AngularJS 通过被称为指令的新属性来扩展 HTML。AngularJS 指令AngularJS 指令是扩展的 HTML 属性,带有...
AngularJS 使用表达式把数据绑定到 HTML。AngularJS 表达式AngularJS 表达式写在双大括号内:{{ expres...
ng-repeat 指令可以完美的显示表格。在表格中显示数据 {{ x.Name }} {{ x.Country }} 使用 CSS 样式为了...
$http是 AngularJS 中的一个核心服务,用于读取远程服务器的数据。读取 JSON 文件下是存储在web服务器上...