Services and Dependency Injection
Angular has a bit of similarity to the .NET ecosystem in regards to handling services. The classes that provide some specific functionalities (like logging) can be brought into other classes (e.g. components) using Dependency Injection. Here’s a simple example:
The highlighted lines show, in order:
- How to create a scope for
- Constructor injection
- Using the injected service.
Services in Angular are just typical TypeScript classes. They do not use any Angular-specific decorator (unless you want to inject into some other service).
The way how we injected the service into the component in the example above has some consequences:
- the child components (direct and indirect) will receive the same instance of
LoggerService(if they ask for it)
- all the other comonents (other than the children of
MyComponent) would receive different instance(s) of
The Angular injector is hierarchical. We can inject services into:
- components -
providersof a module or component
- services -
providersof a module and
Providing a sevice via
SomeComponent makes it a singleton among the children
tree of that component.
Providing a service via the
AppComponent makes it a singleton among all
AppComponent is usually the root of any Angular app).
Providing a service in ANY eager-loaded module
AppModule), makes it a global singleton (for both all the components
and services). T
Providing a service in a lazy-loaded module, makes that service available in entities declared within that module only. If some service is provided both globally and in lazy-loaded module, the lazy-loaded module (and its entities) will get its own instance of that service.
The way how Angular sets up DI is different from the .NET’s way of doing that. In .NET we decide whether the service should be a singleton or not at the aplication root level. In Angular, each class/component may decide whether it wants to reuse some service instance or to get a new one.
Injecting into Services
Services may be injected into other services. Services do not use decorators by
default, so there is no
providers array. Instead, services that want to have
some dependency injected, need to use the special
Here’s an example:
Angular will try to match all the arguments that are required by the
constructor with DI. In this case,
Logger would be injected.
Until now, in the module’s
providers array, we’d just list names of the
services. By default, the class’s name acts as a token that represents that
class. Angular’s injector is more flexible and we can define a token and
dependency to be different things. It’s a bit similar to how in .NET there’s an
interface that classes depend on and a class that actually implements that
interface and gets injected.
Providers can be also defined like this:
The factory injection function can be defined in a separate file, often called
The injection tokens are recommended to be created like this: