Skip to content

Dependency Resolution

Dipend resolves dependencies using a DAG (Directed Acyclic Graph). This ensures that dependencies are resolved in the correct order, without cycles, and only when needed.

A DAG is a graph with:

  • Nodes: Your classes or interfaces (dependencies)
  • Edges: “Depends on” relationships
  • Acyclic: No circular dependencies allowed

This model guarantees a safe, predictable and efficient resolution order, which is critical for building complex systems.

When you call get dependency or resolve singletons, Dipend performs:

  • Graph construction for the dependency tree of App.
  • Topological sort of the nodes to determine creation order.
  • Validation for cycles or missing bindings.
  • Instance creation, respecting the lifecycle of each node (singleton or transient).

This ensures your app is wired safely and correctly, every time.

Consider the following classes:

TypeScript
class Logger {}
class Database {
constructor(private logger: Logger) {}
}
class UserService {
constructor(private db: Database, private logger: Logger) {}
}
Python
class Logger:
pass
class Database:
def __init__(self, logger: Logger):
self._logger = logger
class UserService:
def __init__(self, db: Database, logger: Logger):
self._db = db
self._logger = logger

Dipend builds a graph like this:

Loading graph...

The resolution order will be:

  • Logger
  • Database (which depends on Logger)
  • UserService (which depends on Database and Logger)

No class is constructed before its dependencies are resolved.

Dipend will detect and prevent circular dependencies.

Loading graph...

💥 If you create a circular chain, Dipend will throw an Error during resolution.