Migration from Manual DI¶
How to migrate from a hand-wired container to spryx-di.
Before: Manual Factory¶
class AppContainer:
def __init__(self, db: Database):
self._db = db
self._user_repo = PgUserRepository(db)
self._user_reader = PgUserReader(self._user_repo)
self._team_reader = PgTeamReader(db)
def list_handler(self) -> ListHandler:
return ListHandler(self._user_reader, self._team_reader)
Problems: every new dependency requires manual wiring, no boundary enforcement, hard to test.
After: spryx-di¶
from spryx_di import ClassProvider, ValueProvider, Module, ApplicationContext
identity_module = Module(
name="identity",
providers=[
ClassProvider(provide=UserRepository, use_class=PgUserRepository),
ClassProvider(provide=UserReader, use_class=PgUserReader),
ClassProvider(provide=TeamReader, use_class=PgTeamReader),
],
exports=[UserReader, TeamReader],
)
ctx = ApplicationContext(
modules=[identity_module],
globals=[ValueProvider(provide=Database, use_value=db)],
)
handler = ctx.resolve(ListHandler) # auto-wired
Migration Steps¶
- Identify modules — group related classes by bounded context
- Define ports — extract interfaces (ABCs/Protocols) for cross-module deps
- Create Module definitions — one per bounded context with providers and exports
- Replace manual wiring —
ApplicationContextreplaces the factory class - Update tests — use
Container+ fakes instead of hand-constructing objects