A Composition Root is a single location in your application where all dependencies are composed and wired together. It’s where you configure which implementations to use and how they connect.
NOTE
Sometimes called a “Service Factory” or “Object Graph Builder”, but Composition Root is the standard term.
Why Centralize?
- Single source of truth — All wiring logic in one place
- Easy to swap — Change implementations without touching business logic
- Clear entry point — The app’s dependency structure is visible at a glance
Example
import threading
class CompositionRoot:
_lock = threading.Lock()
_database_service = None
@classmethod
def get_database_service(cls):
if cls._database_service is None:
with cls._lock:
if cls._database_service is None: # Double-check
cls._database_service = DatabaseService()
return cls._database_service
@classmethod
def get_user_service(cls):
return UserService(cls.get_database_service())WARNING
The singleton pattern shown above requires thread-safety. The double-checked locking pattern prevents race conditions when multiple threads initialize the service simultaneously.
Usage
The composition root is typically called at the application’s entry point:
def main():
user_service = CompositionRoot.get_user_service()
user = user_service.get_user(1)
print(user)By centralizing dependency management at the highest level (the entry point), your business logic remains clean and focused—it just receives what it needs.