Angular Advanced DI
Learn Angular Advanced Dependency Injection, including injectors, hierarchical DI, providedIn, inject(), provider types, Injection Tokens, multi providers, lookup decorators (@Self, @SkipSelf, @Host, @Optional), route-level and feature DI, plugin architecture, enterprise best practices, and interview questions.
Learning Objectives
By the end of this lesson, you will understand:
- What Dependency Injection (DI) is.
- Why Angular uses DI.
- How Angular's Injector works internally.
- The Dependency Injection lifecycle.
- Hierarchical Dependency Injection.
- Root Injector.
- Platform Injector.
- Environment Injector.
- Component Injector.
- Route-level Injectors.
- Tree-Shakable Providers.
- The
inject()API. providedInoptions (root,platform,any).- Class Providers.
- Value Providers.
- Factory Providers.
- Existing Providers.
- Injection Tokens.
- Multi Providers.
- Optional Injection.
@Self(),@SkipSelf(),@Host(),@Optional().- Feature-level DI architecture.
- Plugin-based DI.
- Enterprise DI best practices.
- Common mistakes.
- Advanced interview questions.
Introduction
Imagine TechLearningPro has hundreds of components.
Login ComponentDashboardCourse ComponentQuiz ComponentCertificate ComponentAI TutorAdmin Panel
Every component needs services like:
AuthenticationCourse ServiceLoggerHttpClientAnalyticsNotificationConfiguration
Should every component create these services using:
new AuthService()
No.
Angular automatically creates and manages these objects.
This is called Dependency Injection (DI).
What is Dependency Injection?
Dependency Injection is a design pattern where Angular creates required objects (dependencies) and provides them to components or services.
Instead of:
const service = new CourseService();
Angular does:
constructor(private courseService: CourseService){}
Angular automatically injects the service.
Why Dependency Injection?
Without DI:
Component↓new Service()↓Hard Coupling
Problems:
- Difficult to test
- Difficult to replace
- Difficult to maintain
With DI:
Component↓Angular Injector↓Service
The component depends only on the contract, not object creation.
Real-Time Example
TechLearningPro
Course Component↓CourseService↓HttpClient↓Backend API
The component never creates CourseService.
Angular injects it automatically.
Angular DI Architecture
Application Starts↓Create Root Injector↓Register Providers↓Component Requests Service↓Injector Creates Service↓Component Uses Service
What is an Injector?
An Injector is Angular's object factory.
Responsibilities:
- Create services.
- Store services.
- Reuse services.
- Manage service lifetime.
Architecture
Component↓Injector↓Create Object↓Return Service
Service Lifecycle
Suppose:
@Injectable()export class AuthService {}
Application starts.
Root Injector↓AuthService↓Singleton↓Shared Everywhere
Every component receives the same instance.
Root Injector
Most services use:
@Injectable({providedIn:'root'})
Architecture
Application↓Root Injector↓AuthService↓Every Component
Only one instance exists.
Tree-Shakable Providers
Example:
@Injectable({providedIn:'root'})
If the service is never used:
Angular Build↓Unused Service↓Removed
Smaller bundles.
Platform Injector
Some services belong to the Angular platform itself.
Architecture
Browser↓Platform Injector↓Applications
Rarely used directly.
Environment Injector
Modern Angular introduces the Environment Injector.
Architecture
Application↓Environment Injector↓Router↓Feature↓Component
This supports standalone applications and route-level providers.
Component Injector
Services can exist only inside one component.
Example:
@Component({providers:[CourseStore]})
Architecture
Course Component↓CourseStore↓Only This Component
Destroy the component.
The service also disappears.
Route-Level Injector
Modern Angular supports:
{path:'courses',providers:[CourseStore]}
Architecture
Route↓Injector↓CourseStore↓All Child Components
Excellent for feature isolation.
Injector Hierarchy
Angular searches upward.
Component Injector↓Route Injector↓Root Injector↓Platform Injector
If not found:
Angular continues upward.
How Angular Resolves Dependencies
Suppose:
constructor(private logger:LoggerService){}
Angular searches:
Component?↓Route?↓Root?↓Platform?↓Error
inject() API
Modern Angular prefers:
logger = inject(LoggerService);
Instead of constructor injection.
Advantages:
- Cleaner code
- Better readability
- Works inside functions
providedIn Options
Root
providedIn:'root'
Singleton.
Platform
providedIn:'platform'
Shared across applications on the same page.
Any
providedIn:'any'
Creates separate instances for different injectors when appropriate, often useful with lazy-loaded boundaries.
Class Provider
providers:[LoggerService]
Equivalent:
{provide:LoggerService,useClass:LoggerService}
Value Provider
Useful for configuration.
{provide:API_URL,useValue:'https://api.techlearningpro.com'}
Architecture
Injector↓API_URL↓String
Factory Provider
Sometimes service creation is dynamic.
{provide:Logger,useFactory:loggerFactory}
Architecture
Injector↓Factory↓Logger
Existing Provider
Reuse another service.
{provide:Logger,useExisting:ConsoleLogger}
Both tokens reference the same instance.
Injection Tokens
Primitive values require tokens.
export const API_URL =new InjectionToken<string>('API_URL');
Inject:
inject(API_URL);
Architecture
Token↓Injector↓Value
Multi Providers
Useful for plugins.
Example:
{provide:HTTP_INTERCEPTORS,multi:true,useClass:AuthInterceptor}
Another:
{provide:HTTP_INTERCEPTORS,multi:true,useClass:LoggingInterceptor}
Architecture
Injector↓HTTP_INTERCEPTORS↓Interceptor[]↓Many Objects
Optional Injection
Sometimes dependency may not exist.
inject(LoggerService,{optional:true});
If missing:
null
instead of an error.
@Self()
Search only current injector.
Current Component↓Service?↓Yes↓Stop
@SkipSelf()
Ignore current injector.
Start from parent.
Architecture
Skip Current↓Parent↓Root
@Host()
Limit lookup to the current host boundary.
Useful in advanced component composition scenarios.
@Optional()
Dependency may not exist.
Application continues.
Real-Time Example
TechLearningPro
Root↓Authentication↓Logger↓Analytics---------------------Course Route↓CourseStore↓Course Components
Authentication is global.
CourseStore exists only for Course pages.
Feature-Level Architecture
Application│├── Authentication├── Dashboard├── Courses├── Practice└── Admin
Each feature owns:
ServicesSignalsStoresInjectors
Excellent scalability.
Plugin Architecture
Plugin↓Injection Token↓Plugin Loader↓Dynamic Service
Perfect for enterprise platforms.
TechLearningPro Architecture
Root Injector│├── AuthService├── Analytics├── Logger├── Theme│Course Route│├── CourseStore├── QuizStore└── ProgressStore↓Course Components
Enterprise Best Practices
Prefer:
inject()over constructor injection where it improves readability.- Route-level providers.
- Feature-level services.
- Injection Tokens for configuration.
- Multi Providers for extensibility.
- Tree-shakable providers.
Avoid:
- Giant global services.
- Everything inside the Root Injector.
- Creating services using
new. - Tight coupling.
Common Mistakes
Creating Services Manually
Avoid:
const auth =new AuthService();
Always let Angular create services.
Too Many Root Services
Not everything belongs in the Root Injector.
Feature-specific state should remain inside feature injectors.
Configuration Hardcoded
Use:
InjectionToken↓Configuration
Instead of constants scattered across the application.
Massive Services
Split:
CourseServiceQuizServiceCertificateServiceProgressService
Instead of one 5,000-line service.
Enterprise DI Architecture
Browser↓Platform Injector↓Root Injector↓Route Injector↓Component Injector↓Component
Each level owns only what it needs.
Advanced interview questions
Interview Prep
Practice concise answers, then expand each card for the explanation.
1BeginnerQuestionWhat is Dependency Injection?+
Answer
2BeginnerQuestionWhat is an Injector?+
Answer
3BeginnerQuestionWhat is `providedIn:'root'`?+
Answer
4IntermediateQuestionWhy use `inject()`?+
Answer
inject() provides a concise way to obtain dependencies without constructor injection and is especially useful in standalone APIs, guards, interceptors, and factory functions.5IntermediateQuestionWhat are Injection Tokens?+
Answer
6IntermediateQuestionWhat are Multi Providers?+
Answer
7IntermediateQuestionDifference between Root Injector and Component Injector?+
Answer
8AdvancedQuestionWhat is the Injector Hierarchy?+
Answer
9AdvancedQuestionWhat is Tree-Shakable DI?+
Answer
providedIn can be removed from production bundles if they are never used, reducing application size.10AdvancedQuestionWhat is the recommended enterprise architecture?+
Answer
Summary
Dependency Injection is one of Angular's core architectural strengths.
Application Starts│▼Platform Injector│▼Root Injector│▼Route Injector│▼Component Injector│▼Service Resolution│▼Components
For TechLearningPro, an ideal DI architecture is:
Root Injector│├── AuthService├── HttpClient├── AnalyticsService├── LoggerService│├── Angular Course Route│ ├── CourseStore│ ├── ProgressStore│ └── QuizStore│├── Java Course Route│ ├── CourseStore│ └── PracticeStore│└── Admin Route├── UserManagementService└── ReportStore
The core principle: Let Angular create and manage your dependencies. Keep global services in the Root Injector, feature-specific state in route or component injectors, and use Injection Tokens and hierarchical DI to build scalable, testable, enterprise-grade Angular applications.
Next Lesson
Angular HTTP Interceptors — You'll learn:
- Request lifecycle
- Functional interceptors (
HttpInterceptorFn) withInterceptors()- JWT authentication
- Token refresh flow
- Request/response transformation
- Global error handling
- Retry strategies
- Caching
- Request deduplication
- Correlation IDs
- Logging and monitoring
- Loading indicators
- Enterprise interceptor architecture
- Advanced interview questions