Quick Reference
Scene DI는 container를 도입하는 일이 아니라, dependency가 scene과 함께 사라져야 하는지부터 정하는 일입니다. app scope service를 scene entry에 넘기고, scene-local graph는 unload 때 함께 dispose합니다.
| dependency | scope | owner |
|---|---|---|
| account, settings, save repository | app | boot/app root |
| battle state, spawner, HUD presenter | scene/mode | scene composition root |
| popup listener, drag handler | view | presenter/view owner |
| persistent definition asset | asset | project content |
| Addressables scene/asset handle | loading scope | load caller |
AppRoot
-> SaveService, SettingsService
-> Load BattleScene
-> BattleSceneRoot(AppServices)
-> BattleSystem, EnemySpawner, BattleHudPresenter
-> Unload: scene scope Dispose()reference를 연결하는 시점
scene entry root는 serialized scene component와 app-level contract를 받아 scene-local object를 조립합니다. child component가 매번 singleton/locator에서 service를 찾기보다 entry가 constructor, setter, installer 중 프로젝트 규약에 맞는 방법으로 한 번 연결합니다. Inspector reference는 scene object를 가리키고, interface/service contract는 runtime wiring으로 주입되는 경계를 유지합니다.
sceneLoaded event는 OnEnable 뒤 Start 전에 실행됩니다. callback에서 injection할 때 target entry의 active state, app root ready 여부, duplicate subscription을 고려합니다. Start에서 dependency가 항상 준비돼 있다고 가정하지 말고, entry가 initialization completion을 소유하거나 ready signal을 전달합니다.
additive scene과 종료
additive load에서는 active scene이 하나여도 여러 scene scope가 동시에 살아 있습니다. scene name을 global key로만 쓰지 말고 Scene instance·scope ID·owner reference를 기준으로 등록합니다. 하나가 unload될 때 그 scene의 presenter, event listener, pooled object, Addressables handle만 해제하고 app service는 남겨야 합니다.
scene unload 뒤 completion되는 async callback은 destroyed MonoBehaviour에 접근할 수 있습니다. scope cancellation/token, OnDisable unsubscribe, Dispose guard 중 하나로 late callback을 막고, SceneManager.sceneUnloaded에서 어떤 cleanup이 이미 Unity destroy로 처리됐고 어떤 external resource가 남는지 구분합니다.
boundary test
같은 battle scene의 reload, 두 additive scene의 동시 load/unload, scene-local UI close, load 중 cancel을 test합니다. scene A의 HUD event가 scene B에 도착하지 않고, A의 unload가 app SaveService를 dispose하지 않으며, DI wiring이 정확히 한 번 일어나는지 확인합니다.
scene에서 전역 service를 찾는 코드가 늘어나면 DI 경계는 이름만 남습니다. scene root가 한 번 연결하고, child는 받은 contract로 협력하게 하세요.
참고 링크
2 sources