Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Zenject Example SubContainer

いも
September 23, 2019

Zenject Example SubContainer

Unite Tokyo 2019 Eve2 LT Fes の資料です

いも

September 23, 2019
Tweet

More Decks by いも

Other Decks in Programming

Transcript

  1. Zenject Example
    ~Container
    の分割編~
    @
    いも
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  2. いも
    twitter: @adarapata
    ゲーム作ったりしてます
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  3. 宣伝
    「Zenject
    チョットワカルBook
    」を書きました ↓Booth
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  4. 今日話すこと
    Installer
    肥大化問題
    Zenject
    のSubContainer
    について
    Zenject
    チョット触り始めてる人向け
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  5. Installer
    肥大化問題
    public class SomeInstaller : MonoInstaller {
    public override void InstallBindings()
    {
    // Player
    関連のBind
    Container.Bind().AsCached();
    Container.Bind().AsCached(); // Player
    しか依存してない
    Container.Bind().AsCached(); // Player
    しか依存してない
    ~~~
    Container.Bind().AsCached(); // Player
    しか依存してない
    // Enemy
    関連のBind
    Container.Bind().AsCached();
    Container.Bind().AsCached(); // Enemy
    しか依存してない
    }
    }
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  6. Installer
    肥大化問題
    1
    シーンに必要なものがそれなりに大きくなると起きる問題
    あらゆる依存関係が1
    シーンに刻まれる
    Scene
    のInsaller
    が細かい依存関係を知ることになる
    不要な衝突も発生する可能性が出てくる
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  7. 不要な衝突が発生する
    public class SomeInstaller : MonoInstaller {
    public override void InstallBindings() {
    // Player
    関連のBind
    Container.Bind().AsCached();
    Container.Bind().AsCached(); // Player
    しか依存してない
    Container.Bind().AsCached(); // Player
    のLife
    を表現したい
    // Enemy
    関連のBind
    Container.Bind().AsCached();
    Container.Bind().AsCached(); // Enemy
    しか依存してない
    Container.Bind().AsCached(); // Enemy
    のLife
    を表現したい
    }
    }
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  8. 不要な衝突が発生する
    回避できないことはないがちょっと厳しい
    Container
    を分けてスマートにしたい
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  9. やること
    SubContainer
    の利用
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  10. Container
    の階層関係
    Container
    は階層関係を持つことができる
    まず自身のContainer
    を探して、解決できないなら親のContainer

    探す
    親のContainer
    で見つからなかったらその親を~を繰り返す
    ProjectContext
    がどこでもInject
    できるのは、このContainer
    の最上
    位にいるから
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  11. Container
    の階層関係(Parent Contract
    の場合)
    Context
    を境界にContainer
    が繋がっている
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  12. 1Context
    の内部だけでContainer
    の階層関係を作ることもできる
    子にあたるContainer
    のことをSubContainer
    と呼ぶ
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  13. SubContainer
    にPlayer
    が必要とする要素をまとめてしまえば、
    Container
    内部で衝突しない
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  14. FromSubContainerResolve
    public 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

    View full-size slide

  15. FromSubContainerResolve
    Bind
    するオブジェクトをSubContainer
    から探して解決する
    今回だとSubContainer
    からPlayer
    を探して解決する
    このメソッドの後には「何でSubContainer
    を作るか」のBy~~
    メソッ
    ドを定義する
    ByMethod
    メソッドを呼んでInstall
    する
    ByInstaller Installer
    なクラスを呼んでInstall
    する
    ほかにもいっぱいある
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  16. 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

    View full-size slide

  17. Player
    をSubContainer
    から引っ張って解決する
    Life PlayerDependentA
    はContainer
    からは見えない
    Container
    単位で役割をグルーピングしやすい
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  18. GameObjectContext
    public class PlayerBehaviour : MonoBehaviour
    {
    [Inject] PlayerDependentA depA;
    [Inject] Life life;
    }

    こういうのをSubContainer
    でBind
    したいとする
    SubContainer
    にMonoBehavior
    なオブジェクトをBind
    する場合、
    GameObjectContext
    をアタッチする必要がある
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  19. GameObjectContext
    SceneContext 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

    View full-size slide

  20. 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

    View full-size slide

  21. MonoBehaviour
    の場合
    いつものSceneContext
    のノリで対象のPrefab
    にアタッチする
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  22. 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

    View full-size slide

  23. Context
    を跨いで同じことが行われる
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  24. まとめ
    1
    つのContainer
    にどんどんBind
    していくと衝突や可読性の問題が現
    れる
    SubContaienr
    に分離してスコープを狭めよう
    MonoBehaviour
    の場合はGameObjectContext
    を使おう
    MonoBehaviour
    でもPureClass
    でもSubContainer
    の考え方は変わら
    ない。
    Context
    があるかどうかだけ
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide

  25. おわり
    2019/09/23 Unite Tokyo 2019 Eve2 LT Fes

    View full-size slide