skills/dev-skills/angular-developer/references/defining-providers.md
Angular offers automatic and manual ways to provide dependencies to its Dependency Injection (DI) system.
The most common way to provide a service is using providedIn: 'root' on an @Injectable().
Use InjectionToken for non-class dependencies (configuration objects, functions, primitives). An InjectionToken can also be automatically provided.
import {InjectionToken} from '@angular/core';
export interface AppConfig {
apiUrl: string;
}
export const APP_CONFIG = new InjectionToken<AppConfig>('app.config', {
providedIn: 'root',
factory: () => ({apiUrl: 'https://api.example.com'}),
});
You use the providers array when a service lacks providedIn, when you want a new instance for a specific component, or when configuring runtime values.
@Component({
providers: [
// Shorthand for { provide: LocalService, useClass: LocalService }
LocalService,
// useClass: Swap implementations
{provide: Logger, useClass: BetterLogger},
// useValue: Provide static values
{provide: API_URL_TOKEN, useValue: 'https://api.example.com'},
// useFactory: Generate value dynamically
{
provide: ApiClient,
useFactory: (http = inject(HttpClient)) => new ApiClient(http),
},
// useExisting: Create an alias
{provide: OldLogger, useExisting: NewLogger},
// multi: Provide multiple values for the same token as an array
{provide: INTERCEPTOR_TOKEN, useClass: AuthInterceptor, multi: true},
],
})
export class Example {}
provide* functionsLibrary authors should export functions that return provider arrays to encapsulate configuration:
export function provideAnalytics(config: AnalyticsConfig): Provider[] {
return [{provide: ANALYTICS_CONFIG, useValue: config}, AnalyticsService];
}