Basics

Dependency injection deep dive

Injector hierarchy, provider scopes, InjectionToken, and resolution modifiers.

advanced Experienced

Angular DI resolves a dependency by walking a hierarchy of injectors: the element injector chain (component tree) first, then the module/environment injector. The first provider found wins, which is how you override a service for a subtree.

The injector hierarchy is a chain of managers: you ask your team lead first, and the request escalates up the org chart until someone can fulfil it.

Key concepts

1
providedIn: 'root' makes a service a tree-shakeable singleton; providing it in a component’s providers array creates a new instance per component subtree — the basis of scoped state. Non-class dependencies (config, strings) use an InjectionToken.
tree-shakeable singletonnew instance per component subtree`InjectionToken`providedIn: 'root'providers
2
Resolution modifiers tune the lookup: @Optional() returns null instead of throwing, @Self() restricts to the local injector, @SkipSelf() starts at the parent, and @Host() stops at the host component.
Resolution modifiers@Optional()@Self()@SkipSelf()@Host()
3
Pitfall: accidentally re-providing a root service in a component resets its state for that subtree. Interview follow-up: "how would you provide different implementations of the same interface?" — an InjectionToken plus a factory or useClass/useExisting provider.
Pitfall:Interview follow-up:InjectionTokenuseClassuseExisting