对于组件(@Component),我可以使用“providers: []”来添加注入令牌:
export const WINDOW_TOKEN = new InjectionToken<Window>('Window object');
@Component({
providers: [
{ provide: WINDOW_TOKEN, useValue: window }
]
})
export class ExampleClass {
constructor(@Inject(WINDOW_TOKEN) private windowObj: Window) {}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我不必为这个简单的注入创建另一个服务。另外,这WINDOW_TOKEN将仅在ExampleClass. 更重要的是,我的测试用例可以window.open()通过创建一个间谍来测试windowObj
但是,我如何为服务(@Injectable)做类似的事情?
@Injectable({
provideIn: 'root'
})
export class ExampleService {
constructor() {}
}
Run Code Online (Sandbox Code Playgroud)
因此,对于这段代码,我如何创建一个@Inject并仅在 this 中提供ExampleService,而不是创建另一个@Injectable并在根或模块中提供。
您只能在模块级别或组件级别注册服务。
您必须至少注册一个您要使用的任何服务的提供商。提供程序可以是服务自己的元数据的一部分,使该服务在任何地方都可用,或者您可以使用特定的模块或组件注册提供程序。您可以在服务的元数据(在 @Injectable() 装饰器中)或 @NgModule() 或 @Component() 元数据中注册提供程序
当您向特定 NgModule 注册提供程序时,该 NgModule 中的所有组件都可以使用同一个服务实例。要在此级别注册,请使用@NgModule()装饰器的providers属性。
当您在组件级别注册提供程序时,您会通过该组件的每个新实例获得该服务的一个新实例。在组件级别,在@Component()元数据的providers属性中注册服务提供者。
如果要注入另一个服务范围内的服务,则应该将这两个服务封装在同一个模块中。
例如
@NgModule({
declarations: [],
imports: [],
providers: [ServiceA, ServiceB]
})
export class MyModule{}
Run Code Online (Sandbox Code Playgroud)
然后,您可以在您的服务中注入仅在同一服务范围内可用的服务。
@Injectable({})
export class ServiceA{
constructor(private sb: ServiceB) {}
//Service methods
}
Run Code Online (Sandbox Code Playgroud)