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.