Quick Flow
composition root는 object graph를 만들고 dependency를 연결한 뒤 실행 가능한 entry를 반환합니다. bootstrap은 startup·loading·mode selection 같은 runtime 흐름을 조정합니다. 둘을 분리하면 wiring 실패와 gameplay rule 실패의 위치가 달라집니다.
Boot
-> load config / save / required assets
-> composition root: services와 entry를 조립
-> await ready
-> bootstrap: title, tutorial, gameplay 중 다음 흐름 선택
-> scope dispose: unsubscribe, cancel, release| 책임 | owner | 하지 않을 일 |
|---|---|---|
| 생성·interface 연결·config 주입 | composition root | frame마다 service resolve |
| loading·retry·화면/scene 전환 | bootstrap | domain rule을 직접 구현 |
| game rule·state mutation | domain service/system | global locator에서 dependency 찾기 |
| scope 종료 | root가 만든 scope | child가 부모 service를 임의 dispose |
조립이 끝나는 지점
composition root는 SaveRepository, InventoryService, HudPresenter처럼 서로 의존하는 object를 한곳에서 만들고 constructor/field/installer를 통해 연결합니다. root가 반환한 entry는 dependency를 찾지 않고 받은 contract만 사용합니다. runtime object가 ServiceLocator.Resolve로 새 dependency를 가져오기 시작하면 composition boundary가 다시 codebase 전체로 퍼집니다.
Unity scene reference가 필요한 경우 root가 scene entry component를 받아 scene-local dependency를 연결합니다. sceneLoaded callback은 Unity에서 OnEnable 뒤 Start 전에 호출되므로, 이 순서에 의존하는 injection은 scene component가 언제 ready가 되는지와 함께 test합니다. Script Execution Order 값만으로 동일 order script 사이의 순서를 보장하려 하지 않습니다.
bootstrap의 흐름 책임
bootstrap은 loading screen, save validation, authentication, mode routing처럼 어떤 entry를 시작할지를 다룹니다. retry·cancel·failed asset load를 처리하고, 시작 조건이 충족됐을 때만 root가 만든 entry를 start합니다. tutorial completion, quest rule, combat calculation을 bootstrap에 넣으면 시작 파일이 domain controller가 됩니다.
비동기 load가 있다면 ready 이전에 service를 사용하지 않는 contract를 둡니다. failure에서 partial graph를 dispose하고 retry할지, cached graph를 재사용할지 정합니다. bootstrap은 scene 또는 app scope를 만들고, 전환 때 root가 만든 subscription·Addressables handle·pool을 어떤 순서로 해제할지 호출합니다.
경계 test
missing config, corrupted save, duplicate boot scene, load 중 cancel, scene unload 중 late callback을 test합니다. 성공 경로만 실행해 보고 완료하지 말고, root가 만든 object가 정확히 한 번 dispose되는지와 bootstrap이 domain state를 직접 수정하지 않는지 확인합니다.
composition root는 전역 service registry가 아닙니다. 조립 뒤 runtime code가 dependency를 계속 찾아야 한다면 explicit wiring을 끝낸 것이 아닙니다.
참고 링크
2 sources