Posted under Angular
Permalink
Tags Angular, Tip
Providers need to be declared as they ‘provide’ the objects to be injected – in many cases this will be a singleton reused whenever injected (much like a normal Spring bean in Java).
To be visible everywhere in the entire application, they should be declared in the Providers list in the root @NgModule (e.g. app.module.ts).
However if not used globally, they can be for example registered in a component whereupon they will be visible to that component and its children only.
This angular doc here discusses dependency injection and where to register providers.
This angular doc here is the NgModule faq and also discusses the issue. It points out that registering the providers in the root AppModule (@NgModule as above) is the normal use case, and other cases are rare. In particular it makes the following points:-
Should I add application-wide providers to the root AppModule or the root AppComponent?
Register application-wide providers in the root
AppModule
, not in theAppComponent
.Lazy-loaded modules and their components can inject
AppModule
services; they can’t injectAppComponent
services.Register a service in
AppComponent
providers only if the service must be hidden from components outside theAppComponent
tree. This is a rare use case.More generally, prefer registering providers in modules to registering in components.
Discussion
Angular registers all startup module providers with the application root injector. The services created from root injector providers are available to the entire application. They are application-scoped.
Certain services (such as the
Router
) only work when registered in the application root injector.By contrast, Angular registers
AppComponent
providers with theAppComponent
‘s own injector.AppComponent
services are available only to that component and its component tree. They are component-scoped.The
AppComponent
‘s injector is a child of the root injector, one down in the injector hierarchy. For applications that don’t use the router, that’s almost the entire application. But for routed applications, "almost" isn’t good enough.
AppComponent
services don’t exist at the root level where routing operates. Lazy-loaded modules can’t reach them. In the NgModule page sample applications, if you had registeredUserService
in theAppComponent
, theHeroComponent
couldn’t inject it. The application would fail the moment a user navigated to "Heroes".Should I add other providers to a module or a component?
In general, prefer registering feature-specific providers in modules (
@NgModule.providers
) to registering in components (@Component.providers
).Register a provider with a component when you must limit the scope of a service instance to that component and its component tree. Apply the same reasoning to registering a provider with a directive.
For example, a hero editing component that needs a private copy of a caching hero service should register the
HeroService
with theHeroEditorComponent
. Then each new instance of theHeroEditorComponent
gets its own cached service instance. The changes that editor makes to heroes in its service don’t touch the hero instances elsewhere in the application.Always register application-wide services with the root
AppModule
, not the rootAppComponent
.
Leave a Reply
You must be logged in to post a comment.