我正在使用角度cli和角度4。 我已经创建了一些类,我的组件继承了这些类的行为!然而,在开发期间,它们的构造成长,并且在当前阶段,我需要能够允许其他人使用它们,而不需要了解它们的构造函数!
所以在dependency injection中看到Petr消化后 我尝试了,但是由于编译器给出的错误而不得不做一些调整,我想由于角度4和角度5之间存在差异!
这是我的代码:
服务定位器:
import {ReflectiveInjector} from "@angular/core";
export class ServiceLocator {
static injector: ReflectiveInjector;
}
导入serviceLocator的模块:
ServiceLocator.injector = ReflectiveInjector.resolveAndCreate(
Object.keys(services).map(key => ({
provide: services[key].provide,
useClass: services[key].provide,
deps: services[key].deps
}))
);
serviceList:
import {SysFwDatesService} from '../sysDates/sysFwDates.service';
import {MatSnackBar} from '@angular/material';
import {SysFwFormSpecBuilder} from '../uiValidation/SysFwFormSpecBuilder';
import {SysFwHttpApi} from '../http/SysFwHttpApi';
export const services: {[key: string]: {provide: any, deps: any[], useClass?: any}} = {
'SysFwDatesService': {
provide: SysFwDatesService,
deps: []
},
'MatSnackBar': {
provide: MatSnackBar,
deps: []
},
'SysFwFormSpecBuilder': {
provide: SysFwFormSpecBuilder,
deps: []
},
'SysFwHttpApi': {
provide: SysFwHttpApi,
deps: []
}
}
它似乎正在运作,但它似乎已经失去了其他提供商,并期望所有提供商都以这种方式通过!
这是我得到的错误:
没有HttpClient的提供商! (SysFwDatesService - > SysFwHttpApi - > HttpClient的)
我是否需要将所有内容放在servicesList中? 我做错了什么?
在我使用注射器之前一切正常!
感谢您的帮助!
答案 0 :(得分:1)
HttpClient
在HttpClientModule
中定义,并且具有依赖关系层次结构,这些依赖关系不是很容易手动列出为单个providers
数组。 ReflectiveInjector
和Injector
不支持Angular模块,解析模块以手动获取层次结构providers
是不切实际的 - 这是Angular已在内部执行的操作。
初始化服务定位器的模块也应该导入依赖模块,并且生成的注入器应该从模块注入器继承:
@NgModule({ imports: [HttpClientModule], ... })
export class AppModule {
constructor(injector: Injector) {
ServiceLocator.injector = ReflectiveInjector.resolveAndCreate(
Object.keys(services).map(key => ({
provide: services[key].provide,
useClass: services[key].provide,
deps: services[key].deps
})),
injector
);
}
}
顺便说一下,services
对象键不用于任何东西,而且是多余的。 services
可能应该是一个数组。
我强烈建议不要在现实世界的应用程序中使用这个本土服务定位器。这是一个概念的证明,它做了它所做的事情,但也是一个对框架来说不是惯用的黑客,可能会产生很多负面后果,目前可能并不明显,例如:延迟加载的模块。
建议尽可能使用框架提供的方法,这样应用程序最有可能在将来无故障。
是:
@Injectable() // needed for JIT compilation
abstract class Injective {
constructor(protected injector: Injector) {}
}
@Injectable() // potentially needed for AOT compilation
class FooService extends Injective {
baz = this.injector.get(Baz);
}
@Component(...)
class BarComponent extends Injective {
foo = this.injector.get(FooService);
// just passes injector to parent constructor if there's a need for own constructor
constructor(injector: Injector, public baz: Baz) {
super(injector);
// ...
}
}
请注意,为了安全起见,父类和子类都需要@Injectable()
(Angular和Angular CLI版本之间可能会有所不同)。
答案 1 :(得分:0)
您是否尝试过HttpClient
明确指定SysFwHttpApi
作为依赖项?像
'SysFwHttpApi': {
provide: SysFwHttpApi,
deps: [HttpClient]
}