Dependency Injection helps Angular automatically provide the things your components or services need. It saves you from creating or managing those things yourself.
How dependency injection works in Angular
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class MyService { // service code here } import { Component, inject } from '@angular/core'; @Component({ selector: 'app-example', template: `<p>Example works!</p>`, standalone: true }) export class ExampleComponent { private myService = inject(MyService); // use myService in component }
The @Injectable decorator marks a class as available for injection.
The inject() function is used inside components or services to get the dependency.
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class LoggerService { log(message: string) { console.log(message); } }
import { Component, inject } from '@angular/core'; import { LoggerService } from './logger.service'; @Component({ selector: 'app-log-example', template: `<button (click)="logMessage()">Log</button>`, standalone: true }) export class LogExampleComponent { private logger = inject(LoggerService); logMessage() { this.logger.log('Button clicked!'); } }
This example shows a GreetingService that provides a greeting message. The GreetingComponent injects this service and displays the greeting in its template.
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class GreetingService { getGreeting() { return 'Hello from GreetingService!'; } } import { Component, inject } from '@angular/core'; @Component({ selector: 'app-greeting', template: `<h1>{{ greeting }}</h1>`, standalone: true }) export class GreetingComponent { private greetingService = inject(GreetingService); greeting = this.greetingService.getGreeting(); }
Angular creates one instance of a service by default (singleton) when provided in 'root'.
You can inject services in components, other services, or directives.
Using dependency injection makes your app easier to maintain and test.
Dependency Injection lets Angular provide needed services automatically.
Use @Injectable to make a class injectable and inject() to get it.
This helps keep your code clean, reusable, and easy to test.
Practice
Solution
Step 1: Understand dependency injection concept
Dependency injection automatically provides required services to components without manual creation.Step 2: Compare options with this concept
Only To provide components with the services they need automatically describes automatic provision of services, which is the core of dependency injection.Final Answer:
To provide components with the services they need automatically -> Option CQuick Check:
Dependency injection = automatic service provision [OK]
- Thinking you must create service instances manually
- Believing dependency injection restricts service use
- Confusing dependency injection with code organization
Solution
Step 1: Identify Angular decorators for injection
The decorator@Injectablemarks a class as available for dependency injection.Step 2: Eliminate other decorators
@Componentis for components,@NgModulefor modules, and@Inputfor input properties, none make a class injectable.Final Answer:
@Injectable -> Option DQuick Check:
@Injectable = makes class injectable [OK]
- Confusing @Component with @Injectable
- Using @NgModule to make services injectable
- Forgetting to add @Injectable to services
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class LoggerService {
log(message: string) {
console.log('Log:', message);
}
}
import { Component } from '@angular/core';
import { LoggerService } from './logger.service';
@Component({ selector: 'app-root', template: '' })
export class AppComponent {
constructor(private logger: LoggerService) {
this.logger.log('Hello');
}
}Solution
Step 1: Understand service injection in constructor
TheLoggerServiceis injected intoAppComponentvia constructor and used to log a message.Step 2: Analyze the log call
Thelogmethod prints 'Log:' plus the message 'Hello', so console shows 'Log: Hello'.Final Answer:
Log: Hello -> Option AQuick Check:
Injected service logs message correctly [OK]
- Expecting error if service is providedIn root
- Thinking log method won't run without template
- Confusing console output with return value
import { Injectable } from '@angular/core';
@Injectable()
export class DataService {
getData() { return [1, 2, 3]; }
}
import { Component } from '@angular/core';
@Component({ selector: 'app-data', template: '' })
export class DataComponent {
constructor(private dataService: DataService) {}
}Solution
Step 1: Check service provider configuration
The service has@Injectable()but noprovidedInor provider registration, so Angular doesn't know where to provide it.Step 2: Understand injection failure cause
Without being provided, Angular throws an error when injectingDataServiceintoDataComponent.Final Answer:
DataService is not provided in any injector -> Option BQuick Check:
Missing provider causes injection error [OK]
- Assuming @Injectable alone provides the service
- Adding @Component to services incorrectly
- Thinking constructor parameters are optional for injection
Solution
Step 1: Understand multiple instances need
Injecting the same class twice with different configs requires distinguishing them in Angular's injector.Step 2: Use injection tokens for different configs
Angular injection tokens allow providing multiple versions of the same class with different configurations and injecting them separately.Step 3: Evaluate other options
Use@Injectable({ providedIn: 'root' })on the class and inject twice in constructor injects the same instance twice, B duplicates classes unnecessarily, D is error-prone and not recommended.Final Answer:
Use Angular injection tokens to provide different configurations and inject by token -> Option AQuick Check:
Injection tokens enable multiple configured instances [OK]
- Injecting same service twice without tokens
- Creating duplicate service classes unnecessarily
- Changing service config manually at runtime
Ready to prove it?
Pass the test and this pattern moves unknown
