Cycle Detection Example
This example demonstrates how gioc detects circular dependencies both at build-time and at runtime.
What it demonstrates
- Build-time validation with
c.Validate() – catches cycles before any resolution
- Runtime detection – panics with a clear cycle path if
Validate() was skipped
- A valid dependency chain for comparison
Code explanation
Circular dependency
ServiceA -> ServiceB -> ServiceA (cycle!)
ServiceA's constructor takes *ServiceB, and ServiceB's constructor takes *ServiceA. This creates an unresolvable cycle.
Build-time detection (recommended)
Call c.Validate() after all registrations. It performs a DFS on the dependency graph and reports cycles as an error – no panic, no partial initialization.
Runtime detection (fallback)
If Validate() is not called, the container tracks the resolution path during Resolve. When a type appears twice in the path, it panics with the full cycle path.
Valid chain
Database -> Repository -> Service (no cycle)
This resolves successfully, demonstrating that non-cyclic graphs work as expected.
Output
=== Build-time Validation ===
Validation caught the problem:
gioc: validation failed:
circular dependency: *main.ServiceA -> *main.ServiceB -> *main.ServiceA
=== Runtime Detection ===
Runtime panic: gioc: circular dependency detected: *main.ServiceA -> *main.ServiceB -> *main.ServiceA
=== Valid Dependency Chain ===
Service resolved: &{repo:0x...}
Database connection: localhost:5432