我使用Angular 8。
此问题仅适用于Angular DI专家。
起初,我制作了一个Angular库,该库将在许多项目中重复使用。
在这个库中,我提供了一个抽象服务,必须在项目中使用它来定义。
我在我的库中定义了一个名为BridgeService的抽象类
并且在我的主项目中,我创建实现它的BridgeService :(在下一行中,我将向您展示抽象的BridgeService)
MainProject> BridgeService:
import { BridgeService as AbstractBridgeService } from 'myLibrary';
@Injectable()
export class BridgeService implements AbstractBridgeService {
hello(){
alert('hello Word');
}
}
MainProject> UsersModule:
import { UsersModule as LibraryUsersModule } from 'myLibrary';
@NgModule({
imports: [
CommonModule,
LibraryUsersModule,
],
//...
providers: [
BridgeService
// some try:
//{ provide: BridgeService, useClass: BridgeService }
],
})
export class UsersModule {
constructor(private bridgeService: BridgeService){
this.bridgeService.hello();
}
}
现在我们必须查看与库有关的文件:
Library> bridge.service.ts:
export abstract class BridgeService {
abstract hello(): void;
}
此BridgeService必须在UsersModule中定义
Library> UsersModule:
@NgModule({
//...
providers: [
// My Try:
{ provide: BridgeService, useValue: BridgeService}
],
})
export class UsersModule {
# my goal is that I can uncomment this piece of code:
//constructor(private bridgeService: BridgeService){
// this.bridgeService.hello();
//}
}
我希望您仅触摸此代码中的两行:
1)在库的UsersModule提供程序数组中:我要声明为通用的BridgeService行。
2)在项目的UsersModule提供程序数组中:我想定义的BridgeService行代替Library UserModule中的摘要。
仅需在库中定义一个令牌即可。在您的库中,定义令牌和接口:
/** Token to inject the bridge service */
export const BRIDGE_SERVICE_ADAPTER:
InjectionToken<BridgeServiceAdapter> =
new InjectionToken<BridgeServiceAdapter>('Bridge service token');
export interface BridgeServiceAdapter {
hello(): void;
}
在您的库中,您可以像这样注入它:
export class UsersModule {
constructor(
@Inject(BRIDGE_SERVICE_ADAPTER) private bridgeService: BridgeServiceAdapter
){
this.bridgeService.hello();
}
}
而且,在您要使用库的应用程序中:
import { BridgeServiceAdapter } from 'myLibrary';
@Injectable({providedIn: 'root'})
export class BridgeService implements BridgeServiceAdapter {
hello() { alert('hello Word') }
}
...
import { UsersModule as LibraryUsersModule, BRIDGE_SERVICE_ADAPTER } from 'myLibrary';
@NgModule({
imports: [CommonModule,LibraryUsersModule,...],
providers: [{ provide: BRIDGE_SERVICE_ADAPTER, useExisting: BridgeService }],
})
export class UsersModule {
// Obs 1: ok, this seems something you should be encapsulating inside
// your library to doesn't have to inject in the dependent projects
// Obs 2: and, here, in the app, as I created BridgeService decorated
// with {providedIn: 'root'}, I can inject the service itself. But
// if this wasn't the case, I'd have to inject it using the same notation
// used in the library:
// @Inject(BRIDGE_SERVICE_ADAPTER) private bridgeService: BridgeServiceAdapter
// This would be necessary if, I had provided my service like:
// { provide: BRIDGE_SERVICE_ADAPTER, useClass: BridgeService }
// on the above line, notice "useClass" instead of "useExisting"
constructor(private bridgeService: BridgeService) {
this.bridgeService.hello();
}
}