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
needsServiceB
-
ServiceB
also needsServiceA
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) {}
}
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)