Menu
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR ANGULARJS GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SASS VUE GEN AI SCIPY CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING BASH RUST

Angular Advanced DI


Advanced DI uses hierarchical injectors, custom InjectionToken, optional and multi providers, and function-style inject() to compose flexible configurations.


Advanced DI Essentials

  • Scope: Hierarchical injectors mean providers at app/route/component levels define where instances live.
  • Tokens: Use InjectionToken for non-class values and configuration.
  • Function inject: Use inject() in constructors or utility functions.
  • Optional & Multi: Optional dependencies and multi providers enable flexible composition.
import { InjectionToken, inject, Optional } from '@angular/core';

// Tokens
export const CONFIG = new InjectionToken<{ api: string }>('CONFIG');
export const FEATURES = new InjectionToken<string[]>('FEATURES');

// Optional inject
const cfg = inject(CONFIG, { optional: true });

// Multi providers
bootstrapApplication(App, {
  providers: [
    { provide: CONFIG, useValue: { api: '/api' } },
    { provide: FEATURES, useValue: 'search', multi: true },
    { provide: FEATURES, useValue: 'share', multi: true },
  ]
});

Code explained

  • InjectionToken: Defines a typed token for non-class values and configuration.
  • inject(TOKEN, { optional: true }): Retrieves a dependency and returns null/undefined when missing.
  • multi: true: Collects multiple provider values into an array for the same token.

Notes:

  • Related: See Services & DI, Router, and App Bootstrap.
  • Use InjectionToken for configuration, Use function-style inject() in utilities, and scope providers to routes/components when possible.

REMOVE ADS


Advanced DI Example

Example

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, InjectionToken, inject } from '@angular/core';

const FEATURES = new InjectionToken<string[]>('FEATURES');

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h3>DI: Multi Providers</h3>
    <p>Features: {{ features.join(', ') }}</p>
  `
})
class App {
  features = inject(FEATURES);
}

bootstrapApplication(App, {
  providers: [
    { provide: FEATURES, useValue: 'search', multi: true },
    { provide: FEATURES, useValue: 'share', multi: true },
    { provide: FEATURES, useValue: 'ai', multi: true }
  ]
});
<app-root></app-root>

Run Example »

Example explained

  • FEATURES token: A multi provider token that aggregates strings contributed by providers.
  • inject(FEATURES): Reads the aggregated array at runtime.
  • Display: The template joins the features into a comma-separated list.

Notes:

  • Tokens over types: Use InjectionToken for values and interfaces, not classes.
  • Multi providers: Add multi: true to collect many contributions under one token.
  • Scope providers: Use providing at routes/components instead of root when you need isolation.

Optional and Multi Providers

  • Use @Optional() or inject(TOKEN, { optional: true }) when a dependency is not required.
  • Multi providers let many values contribute to the same token.
import { InjectionToken, inject, Optional } from '@angular/core';

export const USER_NAME = new InjectionToken<string>('USER_NAME');

// Constructor optional
constructor(@Optional() public maybeName?: string) {}

// Function optional
const name = inject(USER_NAME, { optional: true });

Example

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, InjectionToken, inject } from '@angular/core';

const USER_NAME = new InjectionToken<string>('USER_NAME');
const FEATURES = new InjectionToken<string[]>('FEATURES');

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h3>Optional & Multi</h3>
    <p>Hello: {{ name || 'Anonymous' }}</p>
    <p>Features: {{ features?.join(', ') || '∅' }}</p>
  `
})
class App {
  name = inject(USER_NAME, { optional: true });
  features = inject(FEATURES, { optional: true });
}

bootstrapApplication(App, {
  providers: [
    // Try commenting USER_NAME to see optional behavior
    { provide: USER_NAME, useValue: 'Dana' },
    { provide: FEATURES, useValue: 'search', multi: true },
    { provide: FEATURES, useValue: 'share', multi: true },
  ]
});
<app-root></app-root>

Example explained

  • Optional inject: inject(USER_NAME, { optional: true }) returns a value when provided or null/undefined when absent.
  • Multi providers: Multiple FEATURES entries are combined into an array.
  • Fallbacks: The template shows defaults when optional values are missing.

Notes:

  • Optional deps: Always handle null when a dependency is optional.
  • Avoid collisions: Name tokens clearly to prevent accidental reuse across features.
  • Config pattern: Model global settings with tokens and override per route/component as needed.


×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
sales@w3schools.com

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
help@w3schools.com

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2025 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.