gpt4 book ai didi

angular - Reflective Injector 和 Injector in Angular 的区别

转载 作者:行者123 更新时间:2023-12-02 08:12:20 29 4
gpt4 key购买 nike

我尝试使用两种方式显式创建依赖关系。两者几乎相同,但我有点困惑使用反射注入(inject)器比普通注入(inject)器有什么优势,推荐使用哪种方式?

使用注入(inject)器

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

使用反射注入(inject)器

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

var injector= ReflectiveInjector.resolveAndCreate([MyService]);
let myservice=injector.get(MyService);
}

最佳答案

注入(inject)器是一个包含提供者/服务的容器。它实现了一个方法 get 并返回服务的一个实例。让我们用 JS 伪代码实现最基本的注入(inject)器版本:

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 });
}
}

现在,我们需要先创建注入(inject)器的实例,然后才能使用它。当我们创建它时,我们定义提供者:

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

所以你看,为了使用注入(inject)器,它必须先被创建。它没有任何允许添加提供者的特定方法,因此在创建后我们无法向其添加任何新的提供者。

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

让我们稍微修改一下 resolveAndCreateget 方法以允许链接注入(inject)器:

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);

现在,假设有人可能想要访问我们的 existingInjector。我们需要一个 token 来获取这个现有的注入(inject)器。让我们像这样定义这个标记:

abstract class Injector {}

然后让我们编写一个函数来获取现有的注入(inject)器:

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 函数中,并返回现有的注入(inject)器。

关于angular - Reflective Injector 和 Injector in Angular 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45441764/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com