Angular中的异步工厂提供程序和组件注入
我对使用异步工厂提供程序创建的依赖项有问题 我有以下配置: 应用程序模块:Angular中的异步工厂提供程序和组件注入,angular,asynchronous,dependency-injection,async-await,factory,Angular,Asynchronous,Dependency Injection,Async Await,Factory,我对使用异步工厂提供程序创建的依赖项有问题 我有以下配置: 应用程序模块: @NgModule({ declarations: [ ... ..., imports: [ BrowserModule, BrowserAnimationsModule, FormsModule, HttpModule, HttpClientModule, ...
@NgModule({
declarations: [
...
...,
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
HttpModule,
HttpClientModule,
...
UsersModule.forRoot(),
...
APP_ROUTERS
]
})
export class AppModule {}
应用程序路由器:
const rootRouters = [
{path: '', redirectTo: 'tests', pathMatch: 'full'},
{
path: 'users/login',
component: SUserLoginComponent,
resolve: {
localUsers: UsersLocalResolver
},
},
{
path: '',
loadChildren: 'app/test/test.module#TestModule',
canActivate: [SecurityAuthenticationGuard],
data: {
preload: true
}
},
];
export const APP_ROUTERS: ModuleWithProviders = RouterModule.forRoot(rootRouters, {onSameUrlNavigation: 'reload'});
@NgModule({
imports: [
CommonModule,
...
],
declarations: [
SUserLoginComponent,
],
exports: [
SUserLoginComponent
]
})
export class UsersModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: UsersModule,
providers: [
UsersLocalResolver,
{
provide: UsersLocalDbServices,
useFactory: (dbservice: IndexedDBService): Promise<UsersLocalDbServices> => {
console.log('Factory UsersLocalDbServices');
return new Promise<UsersLocalDbServices>(async (resolve) => {
if (dbservice.getVersion() === null) {
await dbservice.open(LOCAL_DATABASE_NAME);
}
const instance = new UsersLocalDbServices(dbservice);
const result = await instance.setup();
resolve(instance);
});
},
deps: [IndexedDBService]
}
]
};
}
}
用户模块:
const rootRouters = [
{path: '', redirectTo: 'tests', pathMatch: 'full'},
{
path: 'users/login',
component: SUserLoginComponent,
resolve: {
localUsers: UsersLocalResolver
},
},
{
path: '',
loadChildren: 'app/test/test.module#TestModule',
canActivate: [SecurityAuthenticationGuard],
data: {
preload: true
}
},
];
export const APP_ROUTERS: ModuleWithProviders = RouterModule.forRoot(rootRouters, {onSameUrlNavigation: 'reload'});
@NgModule({
imports: [
CommonModule,
...
],
declarations: [
SUserLoginComponent,
],
exports: [
SUserLoginComponent
]
})
export class UsersModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: UsersModule,
providers: [
UsersLocalResolver,
{
provide: UsersLocalDbServices,
useFactory: (dbservice: IndexedDBService): Promise<UsersLocalDbServices> => {
console.log('Factory UsersLocalDbServices');
return new Promise<UsersLocalDbServices>(async (resolve) => {
if (dbservice.getVersion() === null) {
await dbservice.open(LOCAL_DATABASE_NAME);
}
const instance = new UsersLocalDbServices(dbservice);
const result = await instance.setup();
resolve(instance);
});
},
deps: [IndexedDBService]
}
]
};
}
}
问题是“usersLocalDbService”是一个承诺,而不是服务实例
我通过以下方法解决了这个问题,但事实是,这很可怕:
async ngOnInit() {
this.usersLocalDbService = await this.usersLocalDbService;
}
有没有办法注入由异步工厂实例化的依赖项,并在创建组件之前解决该依赖项?我看到的使用异步工厂的示例(例如)似乎使用了一个返回承诺的函数,而不是直接回报承诺
export class SUserLoginComponent implements OnInit, AfterViewInit {
constructor(private router: Router,
private activatedRoute: ActivatedRoute,
private db: IndexedDBService,
private securityServices: SecurityServices,
private usersLocalDbService: UsersLocalDbServices) {
}
}
将此应用于您的模块将提供:
export class UsersModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: UsersModule,
providers: [
UsersLocalResolver,
{
provide: UsersLocalDbServices,
useFactory: (dbservice: IndexedDBService) => {
return () => {
console.log('Factory UsersLocalDbServices');
return new Promise<UsersLocalDbServices>(async (resolve) => {
if (dbservice.getVersion() === null) {
await dbservice.open(LOCAL_DATABASE_NAME);
}
const instance = new UsersLocalDbServices(dbservice);
const result = await instance.setup();
resolve(instance);
});
}
},
deps: [IndexedDBService]
}
]
};
}
}
导出类用户模块{
static forRoot():ModuleWithProviders{
返回{
ngModule:UsersModule,
供应商:[
UsersLocalResolver,
{
提供:UsersLocalDbServices,
useFactory:(dbservice:IndexedDBService)=>{
return()=>{
log('Factory UsersLocalDbServices');
返回新承诺(异步(解析)=>{
if(dbservice.getVersion()==null){
等待dbservice.open(本地数据库名称);
}
const instance=newuserslocaldbservices(dbservice);
const result=wait instance.setup();
解决(实例);
});
}
},
deps:[索引服务]
}
]
};
}
}
在异步DI方面做了一些努力,但几年前就放弃了。简单的回答是:异步DI是不可能的(使用angular的实现)。看
马克·休斯的回答建议退回承诺工厂。这篇文章是关于在引导过程中使用
APP\u初始化器
令牌执行异步操作的。这不是一般的概念。谢谢你,马克。这个解决方案解决了组件的问题,但是如果我将服务注入到解析器或其他服务中,依赖关系就不是实例(它没有被解析)。这是在解析器构造函数中打印的输出。ƒ(){console.log('Factory UsersLocalDbServices');return new Promise(函数(解析){return_uuuuwaiter(u this,void 0,void 0,function(){…。@CristianRinaldi你有没有一个示例服务显示这个问题?是的,我有一个“poc”我上传它以便你能看到它-我想知道这是否是因为你已经注册TestResolver作为一个提供者而不是作为模块上的声明…嗯,我想不是。我更新了“poc”,如果你运行它,你会看到初始化的顺序,它显示了依赖项是如何被注入的。(在控制台中)