导入模块的顺序覆盖注入模块的抽象。

问题描述 投票:0回答:1

我有一个 TableComponent 其中需要一个抽象服务来做一些异步调用。这个模块看起来像。

@NgModule({
    imports: [
        CommonModule,
    ],
    declarations: [
        TableComponent
    ],
    exports: [
        TableComponent
    ]
})
export class TableModule {

    static forRoot(tableService: Type<TableService>): ModuleWithProviders {
        return {
            ngModule: TableModule,
            providers: [
                { provide: TableService, useClass: tableService }
            ]
        };
    }
}

我还需要进一步的模块: EmployeeModule和LocalizationModule. 看起来都是这样的。

@NgModule({
    imports: [
        CommonModule,
        TableModule.forRoot(EmployeeTableService), <---- Injected EmployeeTableService
    ],
    declarations: [
        EmployeeComponent,
        ModalEmployeeComponent
    ],
    providers: [
        EmployeeResource,
        EmployeeRepository,
        EmployeeTableService
    ]
})
export class EmployeeModule {
}

@NgModule({
    imports: [
        CommonModule,
        TableModule.forRoot(LocalizationTableService),
    ],
    declarations: [
        LocalizationComponent
    ],
    providers: [
        LocalizationResource,
        LocalizationRepository,
        LocalizationTableService
    ],
})
export class LocalizationModule {
}

现在我把这两个模块导入到AppModule中的AppModule中 秩序。. 所以看起来像。

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        HttpClientModule,
        AppRoutes,
        LocalizationModule,
        EmployeeModule
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

这里的问题是顺序问题 取决于哪个模块(员工或本地化)是最后一个模块,服务注入到 TableComponent,它将抽象作为构造函数的参数。即:如果顺序是像上面的那样,只有 EmployeeTableService 是注入的。否则 LocalizationTableService 注入--为什么要这样做,如何改变它,以使 TableComponent 将采取永远正确的抽象?

TableComponent 的样子。

@Component({
    selector: 'sp-table[configuration]',
    templateUrl: './TableComponent.html',
    styleUrls: ['./TableComponent.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class TableComponent implements OnInit {

    constructor(
        public readonly dialog: MatDialog,
        private readonly tableService: TableService,
        private readonly changeDetectorRef: ChangeDetectorRef
    ) {
        super();
    }

EmployeeTableService的例子

@Injectable()
export class EmployeeTableService extends TableService {
    constructor(
        private readonly employeeResource: EmployeeResource
    ) {
        super();
    }

}
angular dependency-injection abstract-class abstract
1个回答
0
投票

如果我的理解正确的话,这里是 爆料


在这种情况下,为什么一个provider会覆盖另一个provider,原因是你定义它们的方式。当您通过 providers 模块的数组,它将被注册在根注入器中。所以,我知道的唯一一个解决方案是重写 TableService 在您每次要使用它的时候,在组件级别上定义它。您也可以在每次使用它时在组件层定义 默认 提供者 TableService 在根注入器中,如果你想使用 TableService 直接。

© www.soinside.com 2019 - 2024. All rights reserved.