Unite Tokyo 2019 Eve2 LT Fes の資料です
Zenject Example~Containerの分割編~@いも2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
View Slide
いもtwitter: @adarapataゲーム作ったりしてます2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
宣伝「ZenjectチョットワカルBook」を書きました ↓Booth2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
今日話すことInstaller肥大化問題ZenjectのSubContainerについてZenjectチョット触り始めてる人向け2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
Installer肥大化問題public class SomeInstaller : MonoInstaller {public override void InstallBindings(){// Player関連のBindContainer.Bind().AsCached();Container.Bind().AsCached(); // Playerしか依存してないContainer.Bind().AsCached(); // Playerしか依存してない~~~Container.Bind().AsCached(); // Playerしか依存してない// Enemy関連のBindContainer.Bind().AsCached();Container.Bind().AsCached(); // Enemyしか依存してない}}2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
Installer肥大化問題1シーンに必要なものがそれなりに大きくなると起きる問題あらゆる依存関係が1シーンに刻まれるSceneのInsallerが細かい依存関係を知ることになる不要な衝突も発生する可能性が出てくる2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
不要な衝突が発生するpublic class SomeInstaller : MonoInstaller {public override void InstallBindings() {// Player関連のBindContainer.Bind().AsCached();Container.Bind().AsCached(); // Playerしか依存してないContainer.Bind().AsCached(); // PlayerのLifeを表現したい// Enemy関連のBindContainer.Bind().AsCached();Container.Bind().AsCached(); // Enemyしか依存してないContainer.Bind().AsCached(); // EnemyのLifeを表現したい}}2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
不要な衝突が発生する回避できないことはないがちょっと厳しいContainerを分けてスマートにしたい2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
やることSubContainerの利用2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
Containerの階層関係Containerは階層関係を持つことができるまず自身のContainerを探して、解決できないなら親のContainerを探す親のContainerで見つからなかったらその親を~を繰り返すProjectContextがどこでもInjectできるのは、このContainerの最上位にいるから2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
Containerの階層関係(Parent Contractの場合)Contextを境界にContainerが繋がっている2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
1Contextの内部だけでContainerの階層関係を作ることもできる子にあたるContainerのことをSubContainerと呼ぶ2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
SubContainerにPlayerが必要とする要素をまとめてしまえば、Container内部で衝突しない2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
FromSubContainerResolvepublic class SomeInstaller : MonoInstaller {public override void InstallBindings() {// SubContainerから解決するContainer.Bind().FromSubContainerResolve().ByMethod(InstallSubContainer);// Enemy関連のBind}// SubContainerにInstallさせるpublic void InstallSubContainer(DiContainer subContainer) {subContainer.Bind().AsCached();subContainer.Bind().AsCached();subContainer.Bind().AsCached();}}2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
FromSubContainerResolveBindするオブジェクトをSubContainerから探して解決する今回だとSubContainerからPlayerを探して解決するこのメソッドの後には「何でSubContainerを作るか」のBy~~メソッドを定義するByMethodメソッドを呼んでInstallするByInstaller Installerなクラスを呼んでInstallするほかにもいっぱいある2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
Installerで解決する場合public class SomeInstaller : MonoInstaller {public override void InstallBindings(){// SubContainerにInstallerでInstallして解決するContainer.Bind().FromSubContainerResolve().ByInstaller().AsCached();// Enemy関連のBind}}public class PlayerInstaller : Installer {public override void InstallBindings(){Container.Bind().AsCached();Container.Bind().AsCached();Container.Bind().AsCached();}}2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
PlayerをSubContainerから引っ張って解決するLife PlayerDependentAはContainerからは見えないContainer単位で役割をグルーピングしやすい2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
GameObjectContextpublic class PlayerBehaviour : MonoBehaviour{[Inject] PlayerDependentA depA;[Inject] Life life;}↑こういうのをSubContainerでBindしたいとするSubContainerにMonoBehaviorなオブジェクトをBindする場合、GameObjectContextをアタッチする必要がある2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
GameObjectContextSceneContext ProjectContextと同じContextの一種ContextはInstallを行うエントリポイントそれぞれInjectionのスコープが違うProjectContext:ゲーム全体SceneContext:シーン内GameObjectContext:アタッチされたGameObject以下SceneContextのContainerにBindするとシーン全体にInjectされるので、GameObjectContextをSubContainerとして狭い範囲へのInjectを行える2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
MonoBehaviorでない場合public class SomeInstaller : MonoInstaller {public override void InstallBindings() {// SubContainerにInstallerでInstallして解決するContainer.Bind().FromSubContainerResolve().ByInstaller().AsCached();}}public class PlayerInstaller : Installer {public override void InstallBindings() {Container.Bind().AsCached();Container.Bind().AsCached();Container.Bind().AsCached();}}SubContainerの作り方が、直接Installerを指定する形になる2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
MonoBehaviourの場合いつものSceneContextのノリで対象のPrefabにアタッチする2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
MonoBehaviourの場合public class SomeInstaller : MonoInstaller {[SerializeField] private GameObject _playerPrefab;public override void InstallBindings() {// GameObjectContextのついたPrefabを生成してInstallするContainer.Bind().FromSubContainerResolve().ByNewContextPrefab(_playerPrefab).AsCached();}}public class SubInstaller : MonoInstaller{public override void InstallBindings() {// Zenject BindingをアタッチするのもアリContainer.Bind().FromComponentOnRoot();Container.Bind().AsCached();Container.Bind().AsCached();}}2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
Contextを跨いで同じことが行われる2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
まとめ1つのContainerにどんどんBindしていくと衝突や可読性の問題が現れるSubContaienrに分離してスコープを狭めようMonoBehaviourの場合はGameObjectContextを使おうMonoBehaviourでもPureClassでもSubContainerの考え方は変わらない。Contextがあるかどうかだけ2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
おわり2019/09/23 Unite Tokyo 2019 Eve2 LT Fes