Recommended Free Tools
Angular resolves a dependency by searching the injector nearest the requesting component or directive first, then moving outward. The first matching provider wins. In modern Angular, that search involves two main hierarchies: ElementInjector for component and directive scope, and EnvironmentInjector for application and other environment-level scope.
Which injector hierarchies does Angular use?
An injector is the place Angular checks for a provider when code requests a dependency. The hierarchy a provider belongs to determines where that dependency is visible and which other provider it can override.
As an Amazon Associate I earn from qualifying purchases.
EnvironmentInjector: application and environment scope
The root EnvironmentInjector is created when an application bootstraps. You can configure environment-level services with a service’s providedIn metadata or with ApplicationConfig.providers. Angular can also create additional environment injectors, including for router scopes and dynamically loaded components. For details, see Angular’s Hierarchical injectors guide.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
ElementInjector: component and directive scope
Angular creates an ElementInjector at each DOM element, empty by default. A component or directive’s providers configures its element injector; a component can also use viewProviders. Components and directives on the same element share that injector. A provider here is available to the component or directive and the descendants that can see it under Angular’s view and content visibility rules.
#1 Best Overall
ModuleInjector: NgModule-based applications
In applications using NgModules, providers in NgModule.providers and recursively reachable imports contribute to the ModuleInjector hierarchy. Lazy-loaded NgModules can create child module injectors. This is the relevant additional hierarchy when reasoning about providers configured through NgModules; modern applications commonly use environment providers instead. Angular describes both models in its hierarchical DI guide.
How does Angular search for a provider?
For a request made by a component or directive, Angular searches in this order:
Rank #2
- Check the requesting element’s
ElementInjector. - Check ancestor
ElementInjectors, moving outward through the element hierarchy. - If no provider matches, return to the requesting element and search its
EnvironmentInjectorancestry. - In an NgModule-based application, search the applicable
ModuleInjectorhierarchy. - If no provider is found, resolution reaches the
NullInjectorand normally fails.
The platform injector sits above the root injector; the NullInjector is the final fallback. The important practical rule is that Angular uses the first matching provider it encounters, rather than combining providers from every level.
Where should a service be provided?
Choose a provider location based on who should share the instance, how long it should live, and where a more specific implementation might be needed.
Rank #3
| Provider location | Typical scope and lifetime | Useful when |
|---|---|---|
providedIn: 'root' or application configuration |
Available from the root environment scope; typically shared across the application unless overridden | The service represents application-wide state or behavior |
| Route or another environment scope | Available within the configured environment scope and its descendants | A feature or route needs its own environment-level dependencies |
Component or directive providers |
Associated with that element injector; a component-provided instance is destroyed when the component is destroyed | A component subtree needs isolated state or a dependency shared only within that subtree |
Component viewProviders |
Configured on the component’s element injector, with component view/content visibility rules applying | A dependency is intended for the component’s own view rather than every projected content consumer |
The table describes scope, not a guarantee that every request creates a new instance: Angular reuses the instance associated with the provider in the relevant injector. If a component is created more than once, each component instance has its own element injector and component-scoped provider instance.
For environment-level service provision, providedIn is the concise option and supports tree-shaking of unused services. Application configuration can override a service’s providedIn: 'root' default. Manual providers are useful when a dependency needs a particular scope or replacement. Angular’s provider definition guide covers automatic provision and manual provider declarations.
Rank #4
How do nearer providers override farther ones?
Suppose LoggerService is provided at the application root and again in a component’s providers. When that component or a descendant requests the service, Angular finds the component-level provider first and returns its instance. Requests elsewhere can still resolve to the root provider. This creates a local override without changing the application-wide default.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →That behavior is useful for isolating state, supplying a feature-specific implementation, or configuring a component subtree independently. It also explains an apparent “duplicate singleton”: a service may be shared within each injector, but registering it again in component-level providers creates a separate instance for that component scope. Component-scoped instances are destroyed with their component.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.How do resolution modifiers change the search?
Angular’s modifiers adjust whether absence is an error, where the search begins, or how far it travels. They are commonly used with the inject() function or constructor injection options. Angular’s hierarchical injector guide documents their detailed behavior.
optional: treat the dependency as optional; if no provider is found, returnnullinstead of failing.self: look only in the current injector. Use it when a dependency must be configured locally rather than inherited.skipSelf: start looking at the parent injector, skipping the current one. This is useful when a local provider needs to delegate to an inherited provider.host: stop the search at the host boundary, subject to Angular’s view and content visibility rules.
Modifiers can be combined to express a more specific lookup. For example, optional lookup avoids an error when a dependency is absent, while skipSelf prevents the current injector’s provider from satisfying the request.
How can you debug a missing or duplicated service?
For a NullInjectorError, follow the same path Angular uses: requesting element, parent element injectors, environment injector, then the final fallback. Angular’s DI debugging and troubleshooting guide provides further diagnosis steps.
Free tools Windows power users keep installed
One-click scans. No signup required.
- Confirm the service is injectable or has a provider declaration, such as
@Injectablewith an appropriateprovidedInvalue. - Check whether the provider is registered in an injector the requesting component can reach.
- For an unexpectedly separate service instance, inspect the requesting component and its ancestors for component-level
providersdeclarations. - Use Angular DevTools’ injector tree inspector to view the hierarchy and providers at each level.
For dependencies that are not classes—such as configuration objects, functions, or primitive values—use an InjectionToken and provide a value or factory for it. Tokens also make the provider identity explicit when the value itself cannot serve as a class token; see Angular’s provider definition guide.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




