⚙️ Services & Dependency Injection

Share state and logic across components using injectable services

About This Feature

Services are classes decorated with @Injectable that provide reusable logic, data access, or shared state. Angular's Dependency Injection (DI) system creates and provides service instances automatically.

  • providedIn: 'root' — singleton shared across the entire app
  • Injected via constructor: constructor(private svc: CounterService)
  • Can use Signals, RxJS, or plain state internally
  • Services are tree-shakeable when using providedIn: 'root'

The demo below shows two completely separate CounterWidget components that both inject the same CounterService singleton — updating one updates both.

Code Example

// counter.service.ts
@Injectable({ providedIn: 'root' })
export class CounterService {
  private _count = signal(0);

  readonly count      = this._count.asReadonly();
  readonly isNegative = computed(() => this._count() < 0);

  increment() { this._count.update(n => n + 1); }
  decrement() { this._count.update(n => n - 1); }
  reset()     { this._count.set(0); }
}

// counter-widget.component.ts
// The service is injected — both widgets share the SAME instance
constructor(public svc: CounterService) {}

// Template: {{ '{{' }} svc.count() {{ '}}' }}

// services.component.html — two widgets, one service
<app-counter-widget label="Widget A" />
<app-counter-widget label="Widget B" />
// Clicking +/- in either widget updates both — shared state!

Live Demo

Both widgets below share the same CounterService instance. Click any button in either widget — both displays update simultaneously.

Widget A

0

Widget B

0
Shared service value read from parent: 0  |  Negative: false