Files
ECC/pi/core/skills/angular-developer/references/injection-context.md
T
Affaan MustafaandGitHub c70874fae9 feat(pi): curated pi/core skills+prompts profile, CI load test, and 2.2.2 release sync (#3264)
Adds a curated, Pi-native, skills+prompts-only profile at pi/core/ for downstream packagers that mirror GitHub Releases.

- manifests/pi-core.json: explicit include lists, per-item exclusion reasons, curation rules, safety allowlists; every root skill and command must be classified.
- scripts/build-pi-core.js regenerates pi/core deterministically (package.json from VERSION, LICENSE, README.md, CURATION.md, skills/, commands/); --check fails CI on drift. council is renamed ecc-council inside pi/core only.
- Safety checks: no callable endpoints outside the allowlist, no npx/curl|sh/pip install, no secrets, no absolute home paths, no symlinks, valid frontmatter, no duplicate names.
- CI: build + drift check and an offline Pi CLI load test of pi/core.
- Release: VERSION, package.json and pi/core/package.json at 2.2.2, CHANGELOG, tag-triggered release verification, and a two-week cadence in CONTRIBUTING.md.

pi/core: 123 of 293 skills and 24 of 94 commands; 35,006 characters of skill description text.
2026-09-29 20:24:05 -05:00

1.9 KiB

Injection Context

The inject() function can only be used when code is executing within an injection context.

Where is an Injection Context Available?

An injection context is automatically available in:

  1. Field initializers of classes instantiated by DI (@Injectable, @Component, @Directive, @Pipe).
  2. Constructors of classes instantiated by DI.
  3. Factory functions specified in useFactory or InjectionToken configurations.
  4. Functional APIs executed by Angular (e.g., functional route guards, resolvers, interceptors).
@Component({...})
export class Example {
  // Valid: Field initializer
  private router = inject(Router);

  constructor() {
    // Valid: Constructor
    const http = inject(HttpClient);
  }

  onClick() {
    // Invalid: Not an injection context
    // const auth = inject(AuthService);
  }
}

runInInjectionContext

If you need to run a function within an injection context (often needed for dynamic component creation or testing), use runInInjectionContext. This requires access to an existing injector (like EnvironmentInjector or Injector).

import {Injectable, inject, EnvironmentInjector, runInInjectionContext} from '@angular/core';

@Injectable({providedIn: 'root'})
export class MyService {
  private injector = inject(EnvironmentInjector);

  doSomethingDynamic() {
    runInInjectionContext(this.injector, () => {
      // Now valid to use inject() here
      const router = inject(Router);
    });
  }
}

assertInInjectionContext

Use assertInInjectionContext in utility functions to guarantee they are called from a valid context. It throws a clear error if not.

import {assertInInjectionContext, inject, ElementRef} from '@angular/core';

export function injectNativeElement<T extends Element>(): T {
  assertInInjectionContext(injectNativeElement);
  return inject(ElementRef).nativeElement;
}