Savvas Nicholas Savvas Nicholas - 3 months ago 29
TypeScript Question

Angular 2 Hierarchical Dependency Injection - Declaring root provider's dependencies outside of root?

(Note I am using Angular 2 RC5)

For simplicity, I have an app like so:

app.module.ts

@NgModule({
providers: [
RootService
],
entryComponents: [AppComponent],
bootstrap: [AppComponent]
})

export class AppModule {}


root.service.ts

import Dependency1 from './somewhere'
import Dependency2 from './somewhere-else'

@Component({
providers: [Dependency1, Dependency2]
})

@Injectable()
export class RootService {
constructor(
private dep1: Dependency1,
private dep2: Dependency2
) {...}
}


An example of a dependency is:

dependency1.ts

@Injectable()
export class Dependency1{
public doGroundbreakingSciencyStuff() {...}
}





My question is: Why, with the above, am I greeted with an error saying:
No provider for PouchSync!
.

I can solve the problem by adding Dependency1 and Dependency2 to the
providers
array in app.module.ts like so:

app.module.ts (fixed)

@NgModule({
providers: [
RootService,
Dependency1,
Dependency2
],
entryComponents: [AppComponent],
bootstrap: [AppComponent]
})

export class AppModule {}


This just seems very ugly. Only
RootService
need to know about these dependencies. Am I doing something wrong here? Or can someone explain why it has to be this way? Surely, when injecting
RootService
, the injector can see that it's dependent on
Dependency1
and
Dependency2
and hence must inject those too, and hence they'll also be application wide singletons.

Answer

Services are not components, so they can't have @Component decorator (which means - it is impossible to add providers array for service class). Conclusion? This code is wrong:

@Component({
    providers: [PouchSync, PouchArraySync]
})

@Injectable()
export class RootService {
    constructor(
        private dep1: Dependency1, 
        private dep2: Dependency2
    ) {...}
}

But your second example is made in angular 2 way.

You wrote that only RootService need to know about dependencies. So if these dependencies are not reusable objects, which should be injected in few pieces of your application, but only available in this class(!) - you should just create instances of them inside your service.

Comments