Angular
Dependency Injection

Chau Tran
twitter.com/@nartc1410
github.com/nartc
Agenda
Syntax
export class SomeRepository {}
export class SomeService {
constructor(private someRepository: SomeRepository) {}
}
export class SomeClass {
constructor(private someService: SomeService) {}
}export class SomeRepository {}
export class SomeService {
@Autowired()
private someRepository: SomeRepository;
}
export class SomeClass {
@Autowired()
private someService: SomeService;
}@Injectable({ providedIn: 'root' })
export class OneService {}
@Injectable()
export class TwoService {}
@Component({
/* ... */,
standalone: true,
providers: [TwoService]
})
export class SomeComponent {
constructor(
private oneService: OneService,
private twoService: TwoService
) {}
}
Injector
bootstrapApplication(AppComponent);bootstrapApplication(AppComponent);bootstrapApplication(AppComponent);RootInjector
PlatformInjector
bootstrapApplication(AppComponent);RootInjector
PlatformInjector
providedIn: 'root'
providedIn: 'platform'
import { bootstrapApplication } from '@angular/platform-browser';
bootstrapApplication(AppComponent);RootInjector
PlatformInjector
providedIn: 'root'
providedIn: 'platform'
import { bootstrapApplication } from '@angular/platform-browser';
bootstrapApplication(AppComponent);RootInjector
PlatformInjector
providedIn: 'root'
providedIn: 'platform'
import { bootstrapApplication } from '@angular/platform-browser';
bootstrapApplication(AppComponent);RootInjector
PlatformInjector
providedIn: 'root'
providedIn: 'platform'
NullInjector
ElementInjector
EnvironmentInjector
ElementInjector
(or NodeInjector)
ElementInjector
(or NodeInjector)
@Component({
providers: [/* here */]
})ElementInjector
(or NodeInjector)
@Component({
providers: [/* here */]
})@Component({
viewProviders: [
/* here */
]
})ElementInjector
(or NodeInjector)
@Component({
providers: [/* here */]
})@Component({
viewProviders: [
/* here */
]
})@Directive({
providers: [/* here */]
})ElementInjector
(or NodeInjector)
@Component({
providers: [/* here */]
})@Component({
viewProviders: [
/* here */
]
})@Directive({
providers: [/* here */]
})Component Tree
ElementInjector
EnvironmentInjector
EnvironmentInjector
EnvironmentInjector
ModuleInjector
EnvironmentInjector
EnvironmentInjector
Outside of Component Tree
EnvironmentInjector
Outside of Component Tree
EnvironmentInjector
Outside of Component Tree
RootInjector
PlatformInjector
NullInjector
EnvironmentInjector
@Injectable({ providedIn: '...' })@Injectable({ providedIn: '...' })EnvironmentInjector
@Injectable({ providedIn: '...' })@Injectable({ providedIn: '...' })bootstrapApplication(AppComponent, {
providers: [/* ... */]
})EnvironmentInjector
@Injectable({ providedIn: '...' })@Injectable({ providedIn: '...' })bootstrapApplication(AppComponent, {
providers: [/* ... */]
})const routes: Route[] = [
{
/* ... */
providers: [/* ... */],
/* ... */
}
]EnvironmentInjector
@Injectable({ providedIn: '...' })@Injectable({ providedIn: '...' })bootstrapApplication(AppComponent, {
providers: [/* ... */]
})const routes: Route[] = [
{
/* ... */
providers: [/* ... */],
/* ... */
}
]@NgModule({
providers: [/* ... */]
})


Injectable
@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Injectable({ providedIn: 'any' })
export class AnyService {}
@Component({})
export class AChildComponent {
constructor(private anyService: AnyService) {}
}
@Component({
imports: [AChildComponent]
})
export class AComponent {
constructor(private anyService: AnyService) {}
}
@Component({})
export class BComponent {
constructor(private anyService: AnyService) {}
}@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Injectable({ providedIn: 'any' })
export class AnyService {}
@Component({})
export class AChildComponent {
constructor(private anyService: AnyService) {}
}
@Component({
imports: [AChildComponent]
})
export class AComponent {
constructor(private anyService: AnyService) {}
}
@Component({})
export class BComponent {
constructor(private anyService: AnyService) {}
}
export const routes: Route[] = [
{
path: 'a',
loadComponent: () => import('./a.component').then(mod => mod.AComponent),
},
{
path: 'b',
loadComponent: () => import('./b.component').then(mod => mod.BComponent),
}
]
@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Component({
providers: []
})@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Component({
providers: []
})@Directive({
providers: []
})@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Component({
providers: []
})@Directive({
providers: []
})@Component({
viewProviders: []
})@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()@Injectable({ providedIn: 'root' })@Injectable({ providedIn: 'platform' })@Injectable({ providedIn: 'any' })@Injectable()Inject, InjectionToken
InjectionToken
Inject, InjectionToken
export const API_URL = new InjectionToken<string>('API Base URL');Inject, InjectionToken
export const API_URL = new InjectionToken<string>('API Base URL');@Inject(API_WINDOW) private apiUrl: stringInject, InjectionToken
export const API_URL = new InjectionToken<string>('API Base URL');@Inject(API_WINDOW) private apiUrl: stringproviders: [{ provide: API_URL, useValue: environment.apiUrl }]Inject, InjectionToken
export const WINDOW = new InjectionToken<Window>('Window');@Inject(API_WINDOW) private apiUrl: stringproviders: [{ provide: API_URL, useValue: environment.apiUrl }]Inject, InjectionToken
export const WINDOW = new InjectionToken<Window>('Window', {
factory: () => {
}
});@Inject(API_WINDOW) private apiUrl: stringproviders: [{ provide: API_URL, useValue: environment.apiUrl }]Inject, InjectionToken
export const WINDOW = new InjectionToken<Window>('WIndow', {
factory: () => {
const document = inject(DOCUMENT);
}
});@Inject(API_WINDOW) private apiUrl: stringproviders: [{ provide: API_URL, useValue: environment.apiUrl }]Inject, InjectionToken
export const WINDOW = new InjectionToken<Window>('Window', {
factory: () => {
const document = inject(DOCUMENT);
return document?.defaultView || null;
}
});@Inject(API_WINDOW) private apiUrl: stringproviders: [{ provide: API_URL, useValue: environment.apiUrl }]Inject, InjectionToken
export const WINDOW = new InjectionToken<Window>('Window', {
providedIn: '...', // default is 'root'
factory: () => {
const document = inject(DOCUMENT);
return document?.defaultView || null;
}
});@Inject(API_WINDOW) private apiUrl: stringproviders: [{ provide: API_URL, useValue: environment.apiUrl }]Provider
Provider
Provider
@Injectable({ providedIn: '...' })Provider
@Injectable()Provider
@Injectable()@Component({ providers: [] })
@Component({ viewProviders: [] })
@Directive({ providers: [] })
const route = { providers: [] }Provider
@Injectable()interface Provider {
provide: InjectionToken | string;
useClass?: Type;
useFactory: (...args: any[]) => any;
useExisting?: Type;
useValue?: any;
}Provider
@Injectable()@Component({
providers: [SomeStore]
})
export class SomeComponent {}Provider
@Injectable()@Component({
providers: [
// SomeStore
{ provide: SomeStore, useClass: SomeStore }
]
})
export class SomeComponent {}Provider
@Injectable()@Component({
providers: [
// SomeStore
{ provide: SomeStore, useExisting: SomeStore }
]
})
export class SomeComponent {}
@Component({
providers: [SomeStore],
imports: [SomeComponent]
})
export class SomeParentComponent {}
Provider
@Injectable(){
provide: API_URL,
useValue: environment.apiUrl
}Provider
@Injectable(){
provide: API_URL,
useFactory: () => {
return environment.apiUrl
},
}Provider
@Injectable(){
provide: API_URL,
useFactory: (configurationService: ConfigurationService) => {
return configurationService.apiUrl;
},
deps: [ConfigurationService]
}Resolution Modifier
Resolution Modifier

Resolution Modifier
@Optional()
@SkipSelf()
@Self()
@Host()inject()
Q/A
Angular Dependency Injection
By Chau Tran
Angular Dependency Injection
- 593