Resolving your dependencies with @Injectable
We took a little deep dive into DI in the previous section, but almost forgot about a very important decorator, @Injectable. @Injectable is not strictly mandatory to use for services in general. However, if that service has dependencies, then it needs to be used. Failure to decorate a service with @Injectable that has dependencies leads to an error where the compiler complains that it doesn't know how to construct the mentioned service. Let's look at a case where we need to use the @Injectable decorator:
import { Injectable } from '@angular/core';
@Injectable()
export class Service {
constructor(logger:Logger) {}
}
In this case, Angular's DI machinery will look up Logger and inject it into the Service constructor. So, providing we have done this:
providers: [Service, Logger]
In a component or module, it should work. Remember, when in doubt, add @Injectable to your service if it has dependencies in the constructor or will have in the near future. If your service lacks the @Injectable keyword and you try to inject it into a component's constructor, then it will throw an error and your component will not be created.
This section set out to explain how DI works from a general standpoint and how it works in Angular. For the latter, it covered how to register constructs to work with Angular's DI machinery, but also how to override it. It is clear that the DI machinery is quite sophisticated. It can be scoped to the application level, by adding constructs to the providers array of Angular modules, but also to the component level and its view children. The main reason for describing the DI machinery was to teach you the possibilities of it, so you know how to best use it to your advantage when you define the architecture of your app.