1

I am aware that Angular2 default DI Context strategy is to enrich an application-wide Dependency Injection Context. But I would like some Injectables to not be globally available.

Here is a concrete example of what I am trying to achieve.

There is probably a doc explaining how to do so but I have not been able to find it.

I would like to create a ServiceModule that would differentiate Public/Exported services from Private services.

@Injectable() export class PrivateService{} // Not available in AppModule
@Injectable() export class PubliclyExportedService{ // Available in AppModule
  constructor(private privateService: PrivateService) { }
}

// The imported module
@NgModule({
  exports: [PubliclyExportedService],
  declarations: [PubliclyExportedService],
  providers: [
    PubliclyExportedService,
    PrivateService
  ]
})
export class ServiceModule {}

// The main module
@NgModule({
  imports: [ServiceModule]
})
export class AppModule { }

The goal is to use the dependency injection so that PubliclyExportedService can use PrivateService but any class outside of the ServiceModule would not be capable of injecting the PrivateService.

Any help is greatly appreciated

Linvi
  • 2,077
  • 1
  • 14
  • 28
  • Did you tried to exclude PrivateService from Module and include it into @Component itself where you're using that service? – DDRamone Jan 30 '17 at 11:51
  • Whats the problem with this, other than declaring a service ? – raj Jan 30 '17 at 11:51
  • @DDRamone I cannot do that because I want the private services to be injected so that they can be mocked. If I follow what you meant, you would have done in the `PubliclyExportedService` constructor a `new PrivateService()`. Am I correct? – Linvi Jan 30 '17 at 14:07
  • @raj The problem is to be able to state what can be resolved from a module. Here with every service being part of the main DI Context you are no longer capable of restricting the access of your module. – Linvi Jan 30 '17 at 14:08
  • @Linvi Your question is about putting that service as `public` or `private`. I suggested a way to keep services `private`. I should inject them via constructor anyway for both `private` or `public` services. (Term `private` isn't correct here, but you guess what i mean. – DDRamone Jan 30 '17 at 14:13
  • *btw*, you dont need to add `PubliclyExportedService` into `exports`. ( https://angular.io/docs/ts/latest/api/core/index/NgModule-interface.html#!#exports-anchor ) – DDRamone Jan 30 '17 at 14:48
  • I do not think there is a way to do it as you wanted it to be injected into services. – raj Jan 30 '17 at 15:06

1 Answers1

0

You can use your private provider (Service) into your every Component, that are using that service:

 @Component({
  ...
  providers: [
    MyPrivateService // <= Using provider into this class
  ]
})
export class FeatureComponent{

  constructor(private _service: MyPrivateSrvice) { }

}

This approach gives you ability not to declare Service as provider into your root module or shared module.

DDRamone
  • 1,078
  • 11
  • 18
  • Good idea, I will try this out tonight and give you some feedback. Are you sure that `@Injectable` decorator have their own `providers` property? I am asking the question as I am not trying to create `@components` here but `@injectables` – Linvi Jan 30 '17 at 14:14
  • @Linvi If it's not `@Component`, you're forced to add it into Module providers (But this makes it to be public for other components). There's no other way i think. I will try to find workaround and update u – DDRamone Jan 30 '17 at 14:34