Skip to main content

Service dependencies

do.ExplainService and do.ExplainNamedService print a single service's dependencies (what it needs to be built) and dependents (what would break if it were removed), recursively, across the scope tree. Use them to understand why a service was instantiated, or to assess the blast radius of removing one.

Dependency tree

Spec

do.ExplainService[T any](do.Injector) (do.ExplainServiceOutput, bool)
do.ExplainNamedService(do.Injector, string) (do.ExplainServiceOutput, bool)

Play: https://go.dev/play/p/GTcGyPFC8IB

debug, found := do.ExplainNamedService(scope, "SERVICE-E")
if found {
println(debug.String())
} else {
println("service not found")
}

Output:

Scope ID: 2a821628-7175-4b6d-a2ea-de8b82a203de
Scope name: scope-child

Service name: SERVICE-E
Service type: lazy
Invoked: github.com/acme/example/main.go:main:42

Dependencies:
* SERVICE-D from scope scope-child
* SERVICE-C1 from scope scope-child
* SERVICE-B from scope [root]
* SERVICE-A1 from scope [root]
* SERVICE-A2 from scope [root]
* SERVICE-C2 from scope scope-child
* SERVICE-B from scope [root]
* SERVICE-A1 from scope [root]
* SERVICE-A2 from scope [root]

Dependents:
* SERVICE-F from scope scope-child
* SERVICE-G from scope scope-child

Play: https://go.dev/play/p/GTcGyPFC8IB

description, found := do.ExplainNamedService(scope, "SERVICE-E")
if found {
println(description.Dependencies)
} else {
println("service not found")
}

Output:

[
{ ScopeID: "6cbfc332-0276-4c28-b0c3-d6256210e4d6", ScopeName: "scope-child", Service: "SERVICE-F", Recursive: [...] },
{ ScopeID: "6cbfc332-0276-4c28-b0c3-d6256210e4d6", ScopeName: "scope-child", Service: "SERVICE-G", Recursive: [...] },
]

Before removing or renaming a service

Check its Dependents list first. An empty list means nothing else in the graph relies on it, so it's safe to remove. A non-empty list tells you exactly which services (and in which scope) would fail to resolve — walk that list recursively to estimate the full blast radius before making the change, rather than deleting the service and waiting for a runtime error to surface the dependency you missed.

See also the scope tree for a graph-wide view, and service registration to list every service currently provided or invoked.