Hard20 minAngular Fundamentals
UpdatedAug 2, 2026
Edit

Angular Dependency Injection Scopes

CONCEPTS:Angular Dependency Injection

Why This Is Asked

Dependency Injection is a pillar of Angular’s architecture. Interviewers ask about scopes (Root, Platform, Component, and Resolution Modifiers) to see if you understand how Angular manages service instances, memory, and state. Knowing how to correctly scope a service is critical for preventing memory leaks and ensuring data is shared (or isolated) correctly across the application.

Key Concepts

  • Tree-shakeable Providers: Using providedIn: 'root'.
  • Hierarchical Injectors: The relationship between the Environment Injector and the Element Injector.
  • providedIn: 'root' vs. Module Providers: Differences in singleton behavior and bundle size.
  • Resolution Modifiers: @Optional(), @SkipSelf(), @Self(), and @Host().

Answers by Technology

+ Add Variant
AngularImprove this answer ✏️

Expected Answer

Angular’s Dependency Injection (DI) system is hierarchical. A service’s “scope” determines where it’s available and how many instances of it exist.

1. The Root Scope (providedIn: 'root')

This is the most common scope. The service is a singleton for the entire application. It is tree-shakeable, meaning if the service is not used anywhere, it won’t be included in the final JavaScript bundle.

2. The Platform Scope (providedIn: 'platform')

A singleton that is shared across multiple Angular applications running on the same page (rare in standard apps, common in micro-frontends).

3. Component/Directive Scope (providers: [...])

When a service is added to a component’s providers array, a new instance of that service is created for every instance of that component. The service is available to that component and all its children.

4. Resolution Modifiers

These decorators change how Angular searches for a dependency:

  • @Optional(): Don’t throw an error if the dependency isn’t found (returns null).
  • @Self(): Only look in the current component’s injector.
  • @SkipSelf(): Start looking in the parent’s injector, skipping the current one.
  • @Host(): Stop looking at the “host” component (the component that contains the template).

Why It Matters

Incorrect scoping leads to two main problems:

  1. State Bugs: Providing a service at the component level when it should be a singleton causes state to be lost when the component is destroyed.
  2. Memory/Performance: Providing everything at the root when some services are only needed for a specific feature can lead to larger initial bundles and unnecessary memory usage.

Understanding hierarchical DI allows you to create sophisticated patterns, like a TabService that is shared only between a TabGroup and its Tab children, but isolated from other TabGroups on the same page.

Example Code

Tree-shakeable Root Provider

@Injectable({
  providedIn: 'root'
})
export class AuthService {}

Component-Level Provider (Isolation)

@Component({
  selector: 'app-user-editor',
  providers: [UserEditStore] // New instance for every editor opened
})
export class UserEditorComponent {
  constructor(private store: UserEditStore) {}
}

Resolution Modifiers

export class MyComponent {
  constructor(
    @Optional() private logger?: LoggerService,
    @SkipSelf() private parentStore: DataStore
  ) {}
}

Common Mistakes

  • Providing a service in both AppModule and a Lazy-Loaded Module: This creates two instances of the service, which often breaks singleton logic (like authentication state).
  • Forgetting providedIn: 'root': Without this or an entry in a providers array, Angular will throw a “No provider for…” error.
  • Overusing Component-level providers: This can lead to difficult-to-debug state issues if you expect a service to be a singleton.

Follow-up Questions

  • What is the difference between providedIn: 'root' and putting a service in AppModule providers? (Answer: providedIn: 'root' is tree-shakeable; AppModule providers are not).
  • How does DI work with Standalone Components? (Answer: You can provide services in the providers array of the @Component decorator or in the bootstrapApplication configuration).
  • What is an Element Injector? (Answer: It’s the injector created for a specific DOM element/component, forming the basis of the DI hierarchy).

References