Angular Di
Angular Dependency Injection specialist for automated service management and decoupled logic integration
Angular DI is a community skill for mastering dependency injection in Angular applications, covering injection tokens, provider hierarchies, factory providers, multi-providers, and tree-shakable service patterns for modular architectures.
What Is This?
Overview
Angular DI provides patterns for leveraging Angular's dependency injection system effectively. It covers injection tokens for creating typed tokens that decouple implementations from their consumers, provider hierarchies with root, component, and route-level scoping for service lifetime control, factory providers using useFactory for creating services with runtime configuration, multi-providers that collect multiple implementations under a single token for plugin architectures, and tree-shakable providers with providedIn that eliminate unused services from production bundles. The skill enables developers to design loosely coupled, testable architectures using Angular's built-in DI system.
Who Should Use This
This skill serves Angular developers designing service architectures with proper scoping, teams building plugin systems using multi-providers and injection tokens, and engineers optimizing bundle size with tree-shakable provider patterns.
Why Use It?
Problems It Solves
Direct class instantiation creates tight coupling that makes testing and substitution difficult. Service scope confusion causes unintended singleton behavior or unnecessary duplicate instances. Runtime configuration of services requires patterns beyond simple class providers. Plugin architectures need extensibility points that collect multiple implementations dynamically.
Core Highlights
InjectionToken creates typed abstract tokens for decoupled dependencies. Provider hierarchy controls service scope from application root to individual components. Factory providers construct services with runtime configuration and conditional logic. Multi-providers collect implementations for extensible hook points.
How to Use It?
Basic Usage
import {
InjectionToken, inject,
Injectable } from
'@angular/core';
// Typed injection token
interface AppConfig {
apiUrl: string;
debug: boolean;
}
const APP_CONFIG =
new InjectionToken<AppConfig>(
'app.config');
// Factory provider
function configFactory():
AppConfig {
return {
apiUrl:
window.location.hostname
=== 'localhost'
? 'http://localhost:3000'
: 'https://api.example.com',
debug:
window.location.hostname
=== 'localhost',
};
}
// Register in app config
// bootstrapApplication(
// AppComponent, {
// providers: [
// { provide: APP_CONFIG,
// useFactory:
// configFactory },
// ],
// });
// Consuming service
@Injectable({ providedIn:
'root' })
export class ApiService {
private config =
inject(APP_CONFIG);
async get<T>(
path: string
): Promise<T> {
const res = await fetch(
`${this.config.apiUrl}`
+ path);
return res.json();
}
}Real-World Examples
import {
InjectionToken, inject
} from '@angular/core';
// Multi-provider plugin system
interface FormValidator {
name: string;
validate(
value: string
): string | null;
}
const FORM_VALIDATORS =
new InjectionToken<
FormValidator[]>(
'form.validators');
const emailValidator:
FormValidator = {
name: 'email',
validate: (v: string) =>
v.includes('@')
? null : 'Invalid email',
};
const lengthValidator:
FormValidator = {
name: 'length',
validate: (v: string) =>
v.length >= 3
? null : 'Too short',
};
// Register validators
// providers: [
// { provide:
// FORM_VALIDATORS,
// useValue: emailValidator,
// multi: true },
// { provide:
// FORM_VALIDATORS,
// useValue: lengthValidator,
// multi: true },
// ]
// Consuming component
class FormFieldComponent {
private validators =
inject(FORM_VALIDATORS);
validate(value: string) {
return this.validators
.map(
(v) => v.validate(value))
.filter(
(e): e is string =>
e !== null);
}
}Advanced Tips
Use inject() function in constructor-less services and functional guards for cleaner dependency resolution. Create component-scoped providers for services that should have separate instances per component. Use abstract classes as injection tokens when you need both a type and a token in a single declaration.
When to Use It?
Use Cases
Build a plugin system where third-party modules register handlers through multi-providers. Create environment-specific service configurations using factory providers with runtime detection. Implement component-scoped form state by providing services at the component level.
Related Topics
Angular dependency injection, injection tokens, provider scoping, factory providers, and multi-providers.
Important Notes
Requirements
Angular 14 or later for the inject() function. TypeScript for typed injection tokens and interfaces. Understanding of Angular injector hierarchy and resolution order.
Usage Recommendations
Do: use InjectionToken with type parameters for type-safe dependency resolution. Prefer providedIn root for application-wide singletons to enable tree-shaking. Use factory providers for services that need runtime configuration.
Don't: provide services in both root and component levels causing confusing duplicate instances. Use string tokens that lack type safety and are prone to collisions. Create circular dependencies between services without using forwardRef.
Limitations
Multi-providers merge all registrations which can cause unexpected behavior if providers are registered in wrong scopes. Factory providers cannot use inject() before Angular 14 requiring constructor-based injection. Deep injector hierarchies can make it difficult to trace which provider instance is being resolved.
More Skills You Might Like
Explore similar skills to enhance your workflow
Shopify
Build Shopify applications, extensions, and themes using GraphQL/REST APIs, Shopify CLI, Polaris UI components, and Liquid templating. Capabilities in
Kotlin MCP Server Generator
kotlin-mcp-server-generator skill for programming & development
Backend Patterns
Implement and automate scalable backend architectural patterns for robust system development
Analyzing Network Traffic with Wireshark
Captures and analyzes network packet data using Wireshark and tshark to identify malicious traffic patterns,
Continual Learning
Implement continuous learning workflows for AI agents to improve over time
GEO Schema & Structured Data
tags: [geo, schema, structured-data, json-ld, entity-recognition, ai-discoverability]