What is Angular's dependency injection hierarchical injector system?

Why Interviewers Ask This

Advanced questions like this reveal whether a candidate has internalized Angular deeply enough to make architectural decisions. Strong answers demonstrate both breadth and depth of experience.

Answer

Angular's DI system uses a hierarchical injector tree that mirrors the component tree, enabling powerful scoping of dependencies. Injector hierarchy (root to leaf): (1) Platform injector: highest level, platform-wide singletons. Services provided here persist across Angular app restarts (rarely used); (2) Root injector (AppModule / bootstrapApplication): services registered here are app-wide singletons. Most services live here via providedIn: "root"; (3) NgModule injectors: lazy-loaded modules get their own injector. Services provided here are scoped to the module; (4) Element injectors: each component/directive has its own injector. Services in @Component({ providers: [] }) create a new instance for that component subtree. Resolution order: when a token is requested, Angular walks up the injector hierarchy: component → parent component → ... → module → root → platform. First match wins. Providing at component level: @Component({ providers: [SessionService] }) — each instance of this component gets its own SessionService instance (not a singleton). Useful for wizard steps, list items with their own state. ViewProviders vs Providers: viewProviders — available only to this component and its view children (NOT content children via ng-content); providers — available to component and ALL children (view + content). @SkipSelf(): skip the current injector, start from parent. @Self(): only look in current injector. @Optional(): inject null if not found (no error). @Host(): stop at the host element injector.

Pro Tip

Back up your answer with a specific project or situation. Saying 'In my last Angular project, I used this when...' immediately makes your answer more credible and memorable.