skills/dev-skills/angular-developer/references/hierarchical-injectors.md
Angular's dependency injection system is hierarchical, meaning services can be scoped to different levels of the application.
EnvironmentInjector Hierarchy: Configured via @Injectable({ providedIn: 'root' }) or ApplicationConfig.providers during bootstrap. These are global singletons.ElementInjector Hierarchy: Created implicitly at each DOM element. Configured via the providers or viewProviders array in @Component() or @Directive().When a dependency is requested, Angular resolves it in two phases:
ElementInjector tree, starting from the requesting component/directive up to the root element.EnvironmentInjector tree, starting from the closest environment injector up to the root.You can alter how Angular searches for a dependency using the options object in inject():
optional: If the dependency isn't found, return null instead of throwing an error.self: Only check the current ElementInjector. Do not look up the parent tree.skipSelf: Start searching in the parent ElementInjector, skipping the current element.host: Stop searching when reaching the host component's view boundary.@Component({...})
export class Example {
// Returns null if not found instead of crashing
optionalService = inject(MyService, { optional: true });
// Skips this component's providers, looks at parent
parentService = inject(ParentService, { skipSelf: true });
}
providers vs viewProvidersWhen providing a service at the component level:
providers: The service is available to the component, its view (template), and any projected content (<ng-content>).viewProviders: The service is available to the component and its view, but NOT to projected content. Use this to isolate services from content passed in by consumers.