All quizzesHard
DI Internals — Series 3
Preview — 3 of 10 questions
Ten different components, all children of the root injector, inject ConfigService in their constructors, all effectively at once during initial render. How many times does 'constructed' log?
javascript
@Injectable({ providedIn: 'root' })
export class ConfigService {
constructor() { console.log('constructed'); }
}AOnce — an injector caches the result of resolving a token the first time it's asked, and returns that same cached instance for every subsequent request against that same injector, regardless of how many separate places ask for it or how close together those requests happen
BTen times — once per component that injects it
CIt's non-deterministic — anywhere from one to ten times, depending on change detection timing
DZero times, because signals defer construction until first read
Every injector in Angular's hierarchy has a parent, all the way up. What is at the very top, above the root injector, and what does it have to do with NullInjectorError?
AThere's nothing above the root injector; "not found" is a special case handled outside the normal injector chain
BThe top of the chain is undefined, and Angular checks for that explicitly to produce the error
CEvery chain terminates in a real, explicit NullInjector — an injector whose get() implementation always throws NullInjectorError (or returns a supplied notFoundValue) for any token, no exceptions. There's no special-cased "ran out of injectors" branch anywhere else; asking the NullInjector for anything is literally what produces the error, unifying "not found" into the exact same "ask the next injector" mechanism used everywhere else in the chain
DThe NullInjector only exists in development builds, as a debugging aid
This factory needs two dependencies, but there's no deps array anywhere. Why does this work, when a useFactory provider without deps (elsewhere) famously does not?
javascript
export const API_CLIENT = new InjectionToken('api client', {
providedIn: 'root',
factory: () => new ApiClient(inject(HttpClient), inject(API_BASE_URL)),
});AIt doesn't actually work; this is a common mistake that silently produces undefined dependencies
BInjectionToken's factory option is special-cased to never need dependencies at all
CAPI_BASE_URL and HttpClient must both also be declared with providedIn: 'root' for this to compile
DWhen Angular invokes an InjectionToken's own factory function, it does so from within an active injection context — the same kind that makes inject() callable inside a component constructor or a functional guard — so the factory can simply call inject() itself for whatever it needs, exactly like any other DI-context-aware code, instead of declaring dependencies positionally through a separate deps array
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.