Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Zenject Example SubContainer
Search
いも
September 23, 2019
Programming
1
12k
Zenject Example SubContainer
Unite Tokyo 2019 Eve2 LT Fes の資料です
いも
September 23, 2019
Tweet
Share
More Decks by いも
See All by いも
UnityプログラミングバイブルR6号宣伝&Unity Logging小話
adarapata
0
400
Unityテスト活動のふりかえり
adarapata
1
510
Gather.townはいいぞ その後
adarapata
1
1.5k
Unityでの開発事例
adarapata
3
22k
どこのご家庭にもあるシーンマネージャーの話
adarapata
1
7.4k
Gather.townはいいぞ
adarapata
2
2.3k
宴はいいぞ
adarapata
0
1.3k
わかった気になるモブプログラミング
adarapata
1
92
モブワークっぽいのをやっている話/Trying mobwork
adarapata
2
1.2k
Other Decks in Programming
See All in Programming
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
4
540
SymfonyCon Vienna 2025: Twig, still relevant in 2025?
fabpot
3
1.2k
rails stats で紐解く ANDPAD のイマを支える技術たち
andpad
1
290
menu基盤チームによるGoogle Cloudの活用事例~Application Integration, Cloud Tasks編~
yoshifumi_ishikura
0
110
Fibonacci Function Gallery - Part 1
philipschwarz
PRO
0
220
今年のアップデートで振り返るCDKセキュリティのシフトレフト/2024-cdk-security-shift-left
tomoki10
0
200
これでLambdaが不要に?!Step FunctionsのJSONata対応について
iwatatomoya
2
3.7k
Jakarta EE meets AI
ivargrimstad
0
250
Итераторы в Go 1.23: зачем они нужны, как использовать, и насколько они быстрые?
lamodatech
0
780
競技プログラミングへのお誘い@阪大BOOSTセミナー
kotamanegi
0
360
DevFest Tokyo 2025 - Flutter のアプリアーキテクチャ現在地点
wasabeef
5
910
テストケースの名前はどうつけるべきか?
orgachem
PRO
0
130
Featured
See All Featured
A designer walks into a library…
pauljervisheath
204
24k
Bash Introduction
62gerente
608
210k
Side Projects
sachag
452
42k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
It's Worth the Effort
3n
183
28k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Making Projects Easy
brettharned
116
5.9k
What's in a price? How to price your products and services
michaelherold
243
12k
Making the Leap to Tech Lead
cromwellryan
133
9k
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
810
The Cult of Friendly URLs
andyhume
78
6.1k
Transcript
Zenject Example ~Container の分割編~ @ いも 2019/09/23 Unite Tokyo 2019
Eve2 LT Fes
いも twitter: @adarapata ゲーム作ったりしてます 2019/09/23 Unite Tokyo 2019 Eve2 LT
Fes
宣伝 「Zenject チョットワカルBook 」を書きました ↓Booth 2019/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 関連のBind Container.Bind<Player>().AsCached(); Container.Bind<PlayerDependentA>().AsCached(); // Player しか依存してない Container.Bind<PlayerDependentB>().AsCached(); // Player しか依存してない ~~~ Container.Bind<PlayerDependentN>().AsCached(); // Player しか依存してない // Enemy 関連のBind Container.Bind<Enemy>().AsCached(); Container.Bind<EnemyDependentA>().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 関連のBind Container.Bind<Player>().AsCached(); Container.Bind<PlayerDependentA>().AsCached(); // Player しか依存してない Container.Bind<Life>().AsCached(); // Player のLife を表現したい // Enemy 関連のBind Container.Bind<Enemy>().AsCached(); Container.Bind<EnemyDependentA>().AsCached(); // Enemy しか依存してない Container.Bind<Life>().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
FromSubContainerResolve public class SomeInstaller : MonoInstaller { public override void
InstallBindings() { // SubContainer から解決する Container.Bind<Player>().FromSubContainerResolve() .ByMethod(InstallSubContainer); // Enemy 関連のBind } // SubContainer にInstall させる public void InstallSubContainer(DiContainer subContainer) { subContainer.Bind<Player>().AsCached(); subContainer.Bind<PlayerDependentA>().AsCached(); subContainer.Bind<Life>().AsCached(); } } 2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
FromSubContainerResolve Bind するオブジェクトをSubContainer から探して解決する 今回だとSubContainer からPlayer を探して解決する このメソッドの後には「何でSubContainer を作るか」のBy~~ メソッ
ドを定義する ByMethod メソッドを呼んでInstall する ByInstaller Installer<T> なクラスを呼んでInstall する ほかにもいっぱいある 2019/09/23 Unite Tokyo 2019 Eve2 LT Fes
Installer で解決する場合 public class SomeInstaller : MonoInstaller { public override
void InstallBindings() { // SubContainer にInstaller でInstall して解決する Container.Bind<Player>().FromSubContainerResolve() .ByInstaller<PlayerInstaller>().AsCached(); // Enemy 関連のBind } } public class PlayerInstaller : Installer<PlayerInstaller> { public override void InstallBindings() { Container.Bind<Player>().AsCached(); Container.Bind<PlayerDependentA>().AsCached(); Container.Bind<Life>().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
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
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
MonoBehavior でない場合 public class SomeInstaller : MonoInstaller { public override
void InstallBindings() { // SubContainer にInstaller でInstall して解決する Container.Bind<Player>().FromSubContainerResolve() .ByInstaller<PlayerInstaller>().AsCached(); } } public class PlayerInstaller : Installer<PlayerInstaller> { public override void InstallBindings() { Container.Bind<Player>().AsCached(); Container.Bind<PlayerDependentA>().AsCached(); Container.Bind<Life>().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<PlayerBehaviour>().FromSubContainerResolve() .ByNewContextPrefab(_playerPrefab).AsCached(); } } public class SubInstaller : MonoInstaller { public override void InstallBindings() { // Zenject Binding をアタッチするのもアリ Container.Bind<PlayerBehavior>().FromComponentOnRoot(); Container.Bind<PlayerDependentA>().AsCached(); Container.Bind<Life>().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