• 共享相同的依赖注入树

    共享相同的依赖注入树

    到目前为止,我们的问题是我们在DI树的不同级别创建相同服务的两个实例。 在树的较低分支中创建的实例会遮蔽在根级别定义的实例。 解决方案? 避免在延迟加载模块的DI树的较低级别中创建第二个实例,并且仅使用在树根处注册的服务实例。

    为了实现这一点,我们需要修改SharedModule的定义,而不是在providers属性中定义我们的服务,我们需要创建一个称为forRoot的静态方法,该方法将与模块本身一起导出服务。

    app/shared/shared.module.ts

    1. import { NgModule, ModuleWithProviders } from '@angular/core';
    2. import { CounterService } from './counter.service';
    3. @NgModule({})
    4. export class SharedModule {
    5. static forRoot(): ModuleWithProviders {
    6. return {
    7. ngModule: SharedModule,
    8. providers: [CounterService]
    9. };
    10. }
    11. }

    通过这个设置,我们可以在我们的根模块AppModule中导入这个模块,调用forRoot方法来注册模块和服务。

    app/app.module.ts

    1. ...
    2. import { SharedModule } from './shared/shared.module';
    3. @NgModule({
    4. imports: [
    5. SharedModule.forRoot(),
    6. ...
    7. ],
    8. ...
    9. })
    10. export class AppModule {}

    相反,当在LazyModule中导入相同的模块时,我们不会调用forRoot方法,因为我们不想在DI树的不同级别注册该服务,因此LazyModule的声明不会改变。

    app/lazy/lazy.module.ts

    1. ...
    2. import { SharedModule } from '../shared/shared.module';
    3. @NgModule({
    4. imports: [
    5. SharedModule,
    6. ...
    7. ],
    8. ...
    9. })
    10. export class LazyModule {}

    View Example

    这次,只要我们更改counter 属性的值,该值就会在EagerComponentLazyComponent之间共享,证明我们正在使用CounterService的同一个实例。