mcpField
A
angular-di

angular-di

github.com/oguzhan18Development7175 installsUpdated 31w ago
Repository

About angular-di

An Angular 21 reference skill for developers configuring dependency injection. It covers inject(), providers, tokens, and injector scopes, with examples for common dependency patterns.

Key features

  1. 01Functional injection with inject()
  2. 02Services and InjectionToken providers
  3. 03Factory and multi providers
  4. 04Optional and SkipSelf dependencies
  5. 05Hierarchical injector scoping

Use cases

  1. 01Inject services into components
  2. 02Provide non-class configuration values
  3. 03Configure multiple implementations
  4. 04Scope services to components or modules

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/oguzhan18/angular-ecosystem-skills --skill angular-di

After installing, type/angular-diin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/discussions/
_INDEX.md
references/docs/
_INDEX.md
references/issues/
_INDEX.md
references/releases/
_INDEX.md

Details

From the project README

Angular Dependency Injection

Version: Angular 21 (2025) Tags: DI, Services, Providers, Tokens, inject()

References: DI Guide • API • inject()

API Changes

This section documents recent version-specific API changes.

  • NEW: Functional injection with inject() — Preferred over constructor injection in modern Angular source

  • NEW: inject() with Optional decorator — inject(Service, { optional: true })

  • NEW: inject() with SkipSelf — inject(Service, { skipSelf: true })

  • NEW: Tree-shakable InjectionToken — new InjectionToken<T>(desc, { providedIn: 'root' })

Best Practices

  • Use providedIn: 'root' for singleton services
@Injectable({ providedIn: 'root' })
export class LoggerService {
  log(message: string) { console.log(message); }
}
  • Use inject() function for cleaner code
@Component({})
export class MyComponent {
  private service = inject(MyService);
  private router = inject(Router);
}
  • Use InjectionToken for non-class dependencies
export const API_URL = new InjectionToken<string>('apiUrl');

providers: [
  { provide: API_URL, useValue: 'https://api.example.com' }
]

constructor(@Inject(API_URL) private apiUrl: string) {}
  • Use factory providers for complex instantiation
providers: [
  {
    provide: AuthService,
    useFactory: (http: HttpClient, config: AppConfig) => {
      return new AuthService(http, config.apiUrl);
    },
    deps: [HttpClient, APP_CONFIG]
  }
]
  • Use multi providers for multiple implementations
providers: [
  { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: LogInterceptor, multi: true }
]
  • Use @Optional for optional dependencies
constructor(@Optional() private logger: LoggerService) {
  this.logger?.log('Optional dependency');
}
  • Use @SkipSelf to avoid self-injection
constructor(@SkipSelf() @Optional() private parent: ParentService) {}
  • Use forwardRef for circular dependencies
constructor(@Inject(forwardRef(() => ParentService)) private parent: ParentService) {}
  • Use hierarchical injectors for scoping
// Component-level provider
@Component({
  providers: [MyService]
})
export class MyComponent {}

// Lazy-loaded module provider
@Injectable({ providedIn: MyModule })
export class MyService {}
  • Use interface injection pattern
export interface CacheInterface {
  get(key: string): any;
}

export const CACHE_TOKEN = new InjectionToken<CacheInterface>('cache');
  • Use providedIn: 'any' for lazy-loaded services
@Injectable({ providedIn: 'any' })
export class LazyService {}

Comments

Markdown supported