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”,如果你运行它,你会看到初始化的顺序,它显示了依赖项是如何被注入的。(在控制台中)