angular
/

Angular Providers – Managing Dependency Injection

Last Sync: Today

On this page

5
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

angular

Angular Providers – Managing Dependency Injection

What is a Provider?

A provider is an instruction to the Dependency Injection system on how to obtain a value for a dependency. Most of the time, you provide a service class, and Angular creates a singleton instance. However, as an architect, you might need to provide a constant value, a different class based on a condition, or a factory function to handle complex initialization logic.

  1. The 'providedIn' Property

Modern Angular recommends providing services directly in the @Injectable decorator using the providedIn property. Using 'root' makes the service a singleton available application-wide and enables 'tree-shaking', meaning the service is only included in the final bundle if it is actually used.

TypeScriptRead-only
1
@Injectable({
  providedIn: 'root' // Singleton, tree-shakable
})
export class AnalyticsService {
  log(msg: string) { console.log('Analytics:', msg); }
}

  1. Provider Recipes

When you need more control, you define providers in an NgModule or a Component. This is where you can swap implementations—perfect for your Revochamp engine when switching between a real AI API and a local mock.

  • useClass: Provides a specific class for an injection token.
  • useValue: Provides a simple fixed value (like a configuration object).
  • useExisting: Maps one token to another existing token (alias).
  • useFactory: Uses a function to dynamically create the dependency.
TypeScriptRead-only
1
providers: [
  // Standard: { provide: Logger, useClass: Logger }
  Logger, 

  // Swapping for a Mock for testing
  { provide: ApiService, useClass: MockApiService },

  // Providing a constant config
  { provide: APP_CONFIG, useValue: { apiEndpoint: 'https://api.revochamp.ai' } }
]

The Injection Hierarchy

Angular's DI system is hierarchical. If a component requests a dependency, Angular looks at that component's providers, then its parent's, and so on, until it reaches the root.

Provider Strategies Comparison

RecipeWhen to UseExample
useClassDefault; swapping implementationsMocking an API service
useValueFixed data or configurationsAPI Keys or feature flags
useFactoryComplex setup involving logicService that needs specific initialization
providedIn: 'root'Standard singletonsMost application services

Test Your Knowledge

Q1
of 3

Which provider property is used to create a singleton service that can be removed if unused?

A
providers: []
B
useValue
C
providedIn: 'root'
D
useFactory
Q2
of 3

Which recipe would you use to provide a simple JSON configuration object?

A
useClass
B
useValue
C
useExisting
D
useConstant
Q3
of 3

In the hierarchy, where does Angular look FIRST for a requested dependency?

A
The root module
B
The current component's providers
C
The browser's local storage
D
The parent component

Frequently Asked Questions

What is an Injection Token?

Sometimes you need to inject things that aren't classes (like a string or an object). An InjectionToken creates a unique 'key' that the DI system can use to find the correct provider for that value.

What happens if I provide a service in a Component instead of Root?

Each instance of that component will get its own separate instance of the service. It is no longer a singleton for the whole app, which is useful for 'sandboxed' logic.

Why is tree-shaking important?

Tree-shaking removes unused code during the build process. By using 'providedIn: root', if you never actually inject the service anywhere, Angular won't include it in your production JavaScript bundle, making your app smaller and faster.

Previous

angular dependency injection

Next

angular routing

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.