adev/src/content/guide/di/overview.md
<docs-decorative-header title="Dependency injection in Angular" imgSrc="adev/src/assets/images/dependency_injection.svg"> <!-- markdownlint-disable-line -->
Dependency Injection (DI) is a design pattern you use to organize and share code across your application by supplying dependencies to a class instead of creating them inside it. </docs-decorative-header>
TIP: Check out Angular's Essentials before diving into this comprehensive guide.
As an application grows, developers often need to reuse and share functionality across different parts of the codebase. Dependency Injection (DI) helps you achieve this by allowing you to provide dependencies to a class instead of creating them directly inside it. This makes different parts of the application more reusable and easier to manage.
Dependency injection is a popular pattern because it allows developers to address common challenges such as:
A dependency is any object, value, function, or service that a class requires to work but does not create itself. Instead, you provide it from the outside, creating a clear relationship between different parts of the application.
You interact with a dependency injection system in two main ways:
In this context, "values" can refer to any JavaScript value, including objects, functions, or class instances. Common types of injected dependencies include:
Angular components and directives automatically participate in DI, meaning that you can inject dependencies into them and make them available for injection.
An Angular service is a TypeScript class decorated with @Injectable, which allows you to inject an instance of the class as a dependency. Services are the most common way of sharing data and functionality across an application.
Common types of services include:
The following example declares a service named AnalyticsLogger:
import {Injectable} from '@angular/core';
@Injectable({providedIn: 'root'})
export class AnalyticsLogger {
trackEvent(category: string, value: string) {
console.log('Analytics event logged:', {
category,
value,
timestamp: new Date().toISOString(),
});
}
}
NOTE: The providedIn: 'root' option makes this service available throughout your entire application as a singleton. This is the recommended approach for most services.
HELPFUL: You can also use the @Service decorator, a ergonomic shorthand for @Injectable({providedIn: 'root'}).
inject()You can inject dependencies using Angular's inject() function.
Here is an example of a navigation bar that injects AnalyticsLogger and Angular Router service to allow users to navigate to a different page while tracking the event.
import {Component, inject} from '@angular/core';
import {Router} from '@angular/router';
import {AnalyticsLogger} from './analytics-logger';
@Component({
selector: 'app-navbar',
template: `<a href="#" (click)="navigateToDetail($event)">Detail Page</a>`,
})
export class Navbar {
private router = inject(Router);
private analytics = inject(AnalyticsLogger);
navigateToDetail(event: Event) {
event.preventDefault();
this.analytics.trackEvent('navigation', '/details');
this.router.navigate(['/details']);
}
}
inject() be used?You can inject dependencies during construction of a component, directive, or service. The call to inject can appear in either the constructor or in a field initializer. Here are some common examples:
@Component({
/*...*/
})
export class MyComponent {
// ✅ In class field initializer
private service = inject(MyService);
// ✅ In constructor body
private anotherService: MyService;
constructor() {
this.anotherService = inject(MyService);
}
}
@Directive({...})
export class MyDirective {
// ✅ In class field initializer
private element = inject(ElementRef);
}
import {Injectable, inject} from '@angular/core';
import {HttpClient} from '@angular/common/http';
@Injectable({providedIn: 'root'})
export class MyService {
// ✅ In a service
private http = inject(HttpClient);
}
export const authGuard = () => {
// ✅ In a route guard
const auth = inject(AuthService);
return auth.isAuthenticated();
};
Angular uses the term "injection context" to describe any place in your code where you can call inject. While component, directive, and service construction is the most common, see injection contexts for more details.
For more information, see the inject API docs.
Now that you understand the fundamentals of dependency injection in Angular, you're ready to learn how to create your own services.
The next guide, Creating and using services, will show you:
providedIn: 'root' pattern worksThis covers the most common use case for services in Angular applications.