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
【re:Growth 2024】 Aurora DSQL をちゃんと話します!
maroon1st
0
770
rails statsで大解剖 🔍 “B/43流” のRailsの育て方を歴史とともに振り返ります
shoheimitani
2
930
Monixと常駐プログラムの勘どころ / Scalaわいわい勉強会 #4
stoneream
0
270
開発者とQAの越境で自動テストが増える開発プロセスを実現する
92thunder
1
180
nekko cloudにおけるProxmox VE利用事例
irumaru
3
420
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
150
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
120
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
1
120
快速入門可觀測性
blueswen
0
340
今年のアップデートで振り返るCDKセキュリティのシフトレフト/2024-cdk-security-shift-left
tomoki10
0
200
DevFest Tokyo 2025 - Flutter のアプリアーキテクチャ現在地点
wasabeef
5
900
Beyond ORM
77web
2
330
Featured
See All Featured
The World Runs on Bad Software
bkeepers
PRO
65
11k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Unsuck your backbone
ammeep
669
57k
Gamification - CAS2011
davidbonilla
80
5.1k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Building an army of robots
kneath
302
44k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
810
A Modern Web Designer's Workflow
chriscoyier
693
190k
Keith and Marios Guide to Fast Websites
keithpitt
410
22k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
45
2.2k
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