的喷射器是与供应商/服务的容器。它实现了一个方法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
和get
方法来允许链接注射器:
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
。我们需要一个令牌来获得这个现有的注射器。让我们来定义此令牌是这样的:
abstract class Injector {}
,让我们写一个函数,将让现有的注射器:
function resolveDependency(token) {
if (token === Injector) {
return existingInjector;
}
}
当执行元件的构造,现在假设角,使用令牌你指定获取依赖关系并将它们传递给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
功能并返回现有的注射器。
'Injector'是一个容器,不能创建新的供应商。 'ReflectiveInjector'具有工厂方法,允许您在运行时定义新的提供者(即创建新的子注入器)。 – cgTag
@ThinkingMedia儿童注射器意味着孩子的依赖? – JEMI
@ThinkingMedia我有一个没有孩子依赖的服务。我想明确地创建它的一个实例。哪一个是推荐的方法? – JEMI