在不同的令牌下提供相同的服务实例

时间:2017-09-21 15:04:24

标签: angular typescript dependency-injection dependencies dependency-management

我有2个接口:

export interface IUserService {
    ...
}

export interface IUserStorageService {
    ...
}

实施这两项服务的单一服务:

@Injectable()
export class UserService implements IUserService, IUserStorageService {
    ...
}

(这部分似乎与这个问题无关,所以它只是为了完整性。我可以轻松地将接口转换为抽象类,直接将它们用作标记而无需额外的注入标记。)
现在,由于Angular不支持接口作为提供者的令牌,我必须创建注入令牌:

export let USER_SERVICE: InjectionToken<IUserService> = new InjectionToken<IUserService>("user.service");

export let USER_STORAGE_SERVICE: InjectionToken<IUserStorageService> = new InjectionToken<IUserStorageService>("user-storage.service");

现在,我可以将这些注入令牌映射到我app.module.ts全局的单个服务类:

@NgModule({
    ...
    providers: [
        { provide: USER_SERVICE, useClass: UserService },
        { provide: USER_STORAGE_SERVICE, useClass: UserService }
    ],
    ...
})
export class AppModule {
    ...
}

最后,我现在能够在不同的接口下注入我的组件:

// Some component - sees service's API as IUserService
constructor(@Inject(USER_SERVICE) private readonly userService: IUserService) {
}

// Another component- sees service's API as IUserStorageService
constructor(@Inject(USER_STORAGE_SERVICE) private readonly userStorageService: IUserStorageService) {
}

这里的问题是Angular实际上创建了2个UserService个实例,每个令牌一个,而我需要UserService为每个应用程序的单个实例。

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

我有一个非常相似的要求:我正在为许多组件提供服务 - 该服务具有dispatchEvent功能和subscribeToEvents功能。我希望它清楚只有管理组件可以使用dispatchEvent(),因此服务implements两个抽象类(这些类可以用作标记 - 比注入标记格式更清晰) - 一个有dispatchEvents,另一个有subscribeToEvents

providers: [
    {provide: AbstractSettingsManager, useClass: SettingsEventService},
    {provide: AbstractSettingsConsumer, useExisting: AbstractSettingsManager}
  ],

您可以使用useExisting密钥,请注意,这意味着&#34;使用现有代币&#34;

这些组件都将具有相同的ServiceEventService实例,但在我提供AbstractSettingsManager / AbstractSettingsConsumer时,组件只能访问(通过TypeScript检查)或其他服务功能