@Injectable({ providedIn: 'root' })
export class LoggerService {
log(message: string) { console.log(message); }
}
// The providedIn root option registers this as a provider automatically at the app level
Topics
42
Accessibility (a11y) in Angular
Angular Animations
Angular CDK (Component Dev Kit)
Angular CLI & Project Structure
Angular DevTools & Debugging
Angular Elements (Web Components)
Angular Material & UI Component Libraries
Angular Material Theming
Angular Schematics & Custom Builders
Angular Security (XSS, Sanitization & CSP)
Angular Signals
Angular Style Guide & Best Practices
Build, Environments & Deployment
Change Detection
Components & Templates
Content Projection (ng-content)
Data Binding
Dependency Injection Providers & Injection Tokens
Directives
End to End Testing with Cypress & Playwright
Forms
HTTP Client & Interceptors
Internationalization (i18n) in Angular
Lifecycle Hooks
Micro Frontends with Angular
New Control Flow Syntax (@if, @for & @switch)
NgModules & Modular Architecture
NgRx State Management
Performance & Lazy Loading
Pipes (Built-in & Custom)
Progressive Web Apps (PWA) with Angular
Router Guards & Resolvers
Routing
RxJS & Observables
Server-Side Rendering with Angular Universal
Services & Dependency Injection
Standalone Components
State Management
Template Reference Variables & ViewChild
Testing with Jasmine & Karma
TypeScript with Angular
Zoneless Change Detection & Zone.js
Dependency Injection Providers & Injection Tokens
5 questions found
A provider tells Angular's dependency injection system how to create a specific value or service when something asks for it. Most commonly this is just the class itself, but a provider can also describe using a different class, a fixed value, or a factory function instead.
Real-world example
A logging service is registered once as a provider at the root of the app, letting any component or service throughout the entire app request and receive the exact same shared instance automatically.
Services & Dependency Injection;Standalone Components
What is an injection token in Angular, and when would you need one instead of just injecting a class?
IntermediateAn injection token is used when you want to inject something that is not a class, such as a plain configuration object or a primitive value, since Angular's dependency injection normally relies on class types as unique identifiers. You create a token using InjectionToken and provide a matching value for it.
import { InjectionToken } from '@angular/core';
export const API_URL = new InjectionToken<string>('API_URL');
// Providing a value for the token
providers: [{ provide: API_URL, useValue: 'https://api.example.com' }]
// Injecting it elsewhere
constructor(@Inject(API_URL) private apiUrl: string) {}
Real-world example
A service needs to know the correct API address to use, and instead of hardcoding it, the app provides that value through an injection token, letting different environments easily supply a different address.
Environment Variables & Configuration;Build
Environments & Deployment
How does the useFactory provider option let you create a service with more complex setup logic?
AdvancedThe useFactory option lets you provide a function that Angular calls to create the actual value, rather than just instantiating a class directly, useful when creating a service requires some conditional logic or depends on other injected services first.
export function loggerFactory(config: AppConfig) {
return config.verboseLogging ? new VerboseLogger() : new SimpleLogger();
}
providers: [
{ provide: LoggerService, useFactory: loggerFactory, deps: [AppConfig] }
]
Real-world example
An app provides either a detailed, verbose logging service or a simple, minimal one depending on a configuration setting, using a factory provider to decide which specific implementation to actually create at startup.
Services & Dependency Injection;Angular Signals
useClass tells Angular to create a brand new instance of a different class when something asks for the original one, useful for swapping implementations, such as during testing. useExisting instead reuses an already existing instance of another service, making both names point to the exact same single instance rather than creating a separate one.
// useClass, creates a new, separate instance of a different class
providers: [{ provide: LoggerService, useClass: MockLoggerService }]
// useExisting, reuses the same existing instance under a different name
providers: [{ provide: OldLoggerService, useExisting: LoggerService }]
Real-world example
A test suite replaces the real LoggerService with a MockLoggerService using useClass, letting tests verify logging behavior without actually writing anything to the real console output.
Testing with Jasmine & Karma;Services & Dependency Injection
Setting providedIn to root tells Angular to make this service available application wide, using a single shared instance, without needing to manually list it in any component's or module's providers array. This is the most common and simplest way to register a service in modern Angular.
@Injectable({ providedIn: 'root' })
export class CartService {
items: string[] = [];
}
// Now injectable anywhere in the app without any extra setup
constructor(private cartService: CartService) {}
Real-world example
A shopping cart service registered with providedIn root is automatically available to every component across the entire app, sharing the exact same cart data everywhere it is injected.
Services & Dependency Injection;NgModules & Modular Architecture