Services & Dependency Injection
Basic Service
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Singleton across app
})
export class UserService {
private users: string[] = [];
getUsers() {
return this.users;
}
addUser(user: string) {
this.users.push(user);
}
}
Inject in Component
import { Component, inject } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'app-user-list',
standalone: true
})
export class UserListComponent {
// Modern inject() function
userService = inject(UserService);
// Or constructor injection (traditional)
constructor(private userService: UserService) {}
users = this.userService.getUsers();
}
Provide Levels
// Root level (singleton)
@Injectable({ providedIn: 'root' })
// Component level (new instance per component)
@Component({
providers: [UserService]
})
// Module level (deprecated with standalone)
@NgModule({
providers: [UserService]
})
Injection Tokens
import { InjectionToken } from '@angular/core';
export const API_URL = new InjectionToken<string>('api.url');
// Provide
@Component({
providers: [
{ provide: API_URL, useValue: 'https://api.example.com' }
]
})
// Inject
apiUrl = inject(API_URL);
Factory Providers
export function userServiceFactory(http: HttpClient) {
return new UserService(http, '/api/users');
}
@Component({
providers: [
{
provide: UserService,
useFactory: userServiceFactory,
deps: [HttpClient]
}
]
})
Best Practices
- Use
providedIn: 'root'for app-wide services - Use component providers for component-specific state
- Prefer
inject()over constructor injection (modern) - Keep services stateless when possible
- Use interfaces for abstraction