防止服务注入到另一个服务

时间:2017-07-28 07:15:52

标签: angular

我使用ngx-toastr库来显示通知。此库包含ToastrService。但是,我想为这个服务创建自己的包装器,因为我需要为不同类型的消息配置不同的配置。所以我有:

@Injectable()
export class NotificationService {
  constructor(private toastrService: ToastrService) {
  }

  public success(message: string, title?: string): void {
    this.toastrService.success(message, title);
  }

  public error(message: string, title?: string): void {
    let toastConfig = {
      ...
    };
    this.toastrService.error(message, title, toastConfig);
  }

  public info(message: string, title?: string): void {
    let toastConfig = {
      ...
    };
    this.toastrService.info(message, title, toastConfig);
  }

  public warning(message: string, title?: string): void {
    this.toastrService.warning(message, title);
  }
}

我想阻止其他开发人员在某处注入ToastrService。如果用户将ToastrService注入组件或除NotificationService之外的其他服务,我想抛出错误。我怎么能这样做?

模块:

@NgModule({
  imports: [
    ToastrModule.forRoot(),
  ],
  declarations: [],
  providers: [    
    NotificationService
  ],
  exports: []
})

1 个答案:

答案 0 :(得分:1)

  

如果用户将ToastrService注入组件或除。之外的其他服务   NotificationService我想抛出错误。

你不需要这样做。让他们全部使用通常的令牌ToastrService来使用服务但是他们将获得装饰NotificationService的实例

此库在模块级别声明ToastrService。您可以在同一令牌下在根组件级别重新定义此服务:

@Component({
   providers: [
      { provide: ToastrService, useClass: NotificationService} 
})
export class AppRootComponent {}

当作为根应用程序组件的子项的任何组件请求该服务时,它将获得该服务的修饰版本。

如果您仍想抛出错误(虽然我认为这不是装饰的方式),您可以这样做:

class ToastrServiceThatThrows { 
    constructor() { throw new Error('I should not be instantiated') } 
}

@Component({
   providers: [
      { NotificationService  },
      { provide: ToastrService, useClass: ToastrServiceThatThrows }  
})
export class AppRootComponent {}

但您必须在@SkipSelf()上使用NotificationService装饰器:

@Injectable()
export class NotificationService {
  constructor(@SkipSelf() private toastrService: ToastrService) {  }

这样你就可以从模块注入器中获得真正的类实例。并且不要在模块上注册NotificationService,只在根组件上注册。