DEV Community

Benjamin Arambide
Benjamin Arambide

Posted on

How can you handle circular dependencies between Angular services without breaking the dependency injection system?

Angular provides a built-in function called forwardRef that allows you to resolve circular dependencies elegantly.

πŸ” What is a Circular Dependency?

A circular dependency occurs when two classes depend on each other. For example:

  • ServiceA needs ServiceB
  • ServiceB also needs ServiceA

This creates a loop that Angular can't resolve at compile time.

πŸ› οΈ The Solution: forwardRef

You can use forwardRef to tell Angular: "Don't resolve this dependency now β€” wait until everything is defined."

βœ… Example:

@Injectable()
export class ServiceA {
  constructor(@Inject(forwardRef(() => ServiceB)) private serviceB: ServiceB) {}
}

@Injectable()
export class ServiceB {
  constructor(private serviceA: ServiceA) {}
}

Enter fullscreen mode Exit fullscreen mode

In this example:

We delay resolving ServiceB inside ServiceA until runtime.

This breaks the circular resolution problem.

🧠 Why It Works

Angular's DI system builds providers in a certain order.
If a token isn’t defined when it's injected, it fails.
But forwardRef(() => Type) defers the reference resolution to runtime β€” by then, Angular knows what ServiceB is.

🎯 When to Use

Use it when two services must reference each other, and you can’t redesign the architecture easily.

Use sparingly. If you use it often, it's a sign your services may be too tightly coupled.

πŸ“Œ Summary

Circular dependencies break DI β€” but forwardRef solves this.

It allows lazy resolution of dependencies in services and components.

It's a powerful Angular feature that many devs overlook or misuse.

Top comments (0)