Hierarchical Injection using Injection Tokens

Demonstrate how InjectionTokens can be provided at different levels of an Angular application to control the scope of the injected values.
import { Injectable, InjectionToken, NgModule } from '@angular/core';

// Define an injection token
export const MY_CONFIG_TOKEN = new InjectionToken('my_config');
Defines a custom InjectionToken called MY_CONFIG_TOKEN.
// App-wide configuration value
const appConfig = {
  appTitle: 'Application Title'
Defines a configuration object that might be injected at the root level.
  providedIn: 'root',
  useValue: appConfig
export class AppConfigService {
  constructor(@Inject(MY_CONFIG_TOKEN) public config: any) {}
Creates the AppConfigService which can be provided at the root level using the configured value.
  providers: [{ provide: MY_CONFIG_TOKEN, useValue: appConfig }]
export class AppModule {}
Provides the MY_CONFIG_TOKEN at the AppModule level, effectively making it available app-wide.
// Component-level configuration override
const componentConfig = {
  appTitle: 'Component Specific Title'
Defines a configuration object to demonstrate a possible override at the component level.
  selector: 'my-component',
  template: '<h1>{{ configService.config.appTitle }}</h1>',
  providers: [{ provide: MY_CONFIG_TOKEN, useValue: componentConfig }]
export class MyComponent {
  constructor(public configService: AppConfigService) {}
Provides the MY_CONFIG_TOKEN at the MyComponent level with a specific override, which will only affect the MyComponent's instance of AppConfigService.