Skip to content

Commit 77ea67f

Browse files
committed
Update README
1 parent 19d459b commit 77ea67f

File tree

2 files changed

+119
-47
lines changed

2 files changed

+119
-47
lines changed

README.md

Lines changed: 87 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,30 @@ Asynchronous DI Container for Unity
99

1010
* [日本語Readmeはこちら](https://github.com/mewlist/Doinject/blob/main/README_ja.md)
1111

12-
## Documentation
12+
## Table of Contents
13+
14+
- [Documentation](#documentation)
15+
- [Example Project](#example-project)
16+
- [Installation](#installation)
17+
- [Install via Unity Package Manager](#install-via-unity-package-manager)
18+
- [About Doinject](#about-doinject)
19+
- [Concepts](#concepts)
20+
- [Asynchronous DI Containers](#asynchronous-di-containers)
21+
- [Context Scopes Aligned with Unity's Lifecycle](#context-scopes-aligned-with-unitys-lifecycle)
22+
- [Integration with the Addressable Asset System](#integration-with-the-addressable-asset-system)
23+
- [Simplified Dependency Patterns](#simplified-dependency-patterns)
24+
- [Binding](#binding)
25+
- [Type Binding](#type-binding)
26+
- [MonoBehaviour Binding](#monobehaviour-binding)
27+
- [Addressables Binding](#addressables-binding)
28+
- [Factory Binding](#factory-binding)
29+
- [Injection](#injection)
30+
- [Installer](#installer)
31+
- [Constructor Injection](#constructor-injection)
32+
- [Method Injection](#method-injection)
33+
- [Injection into MonoBehaviours](#injection-into-monobehaviours)
34+
35+
## Documentation
1336

1437
[![Build documentation](https://github.com/mewlist/Doinject/actions/workflows/writerside.yml/badge.svg)](https://github.com/mewlist/Doinject/actions/workflows/writerside.yml)
1538

@@ -25,7 +48,6 @@ Asynchronous DI Container for Unity
2548

2649
### Install via Unity Package Manager
2750

28-
Install via Unity Package Manager
2951
Please install the packages in the following order:
3052

3153
```
@@ -38,61 +60,71 @@ https://github.com/mewlist/Doinject.git
3860

3961
# About Doinject
4062

41-
Doinject is an asynchronous DI (Dependency Injection) framework for Unity.
63+
Doinject is an asynchronous Dependency Injection (DI) framework for Unity.
4264

43-
The concept of asynchronous DI containers is the starting point.
44-
Unity 2022 LTS / Unity 6 are supported.
65+
It is built around the concept of an asynchronous DI container.
66+
Supports Unity 2022.3 LTS / Unity 6 and later.
4567

4668
## Concepts
4769

4870
### Asynchronous DI Containers
4971

50-
Typical DI containers perform a synchronous process when generating registered types.
51-
However, it cannot support the asynchronous instantiation function used in Unity or instance creation methods that require some kind of asynchronous processing.
72+
Traditional DI containers typically create instances synchronously.
73+
However, this approach doesn't easily support Unity's asynchronous operations, such as loading assets or fetching data before an object can be fully initialized.
5274

53-
By introducing Doinject, you can use a DI container that supports instance creation and release through asynchronous processing.
54-
This allows instance creation with asynchronous loading through Addressables Asset Systems, or instance creation based on information loaded from asynchronous IO.
55-
It becomes possible to perform more flexible instance management with simple descriptions.
56-
By creating a custom factory, you can create instances that involve any asynchronous processing.
75+
Doinject provides a DI container designed for asynchronous workflows. It supports creating and disposing of instances through asynchronous processes.
76+
This allows for more flexible dependency management with a clear API, enabling scenarios like:
77+
* Instantiating objects after asynchronously loading their prefabs or assets via the Addressables system.
78+
* Initializing services with data fetched asynchronously from a network or file.
79+
Custom factories can be created to handle any asynchronous instantiation logic.
5780

58-
### Context Space Consistent with Unity's Lifecycle
81+
### Context Scopes Aligned with Unity's Lifecycle
5982

60-
Designed to define context spaces in a way that does not conflict with Unity's lifecycle.
61-
When a scene is closed, the context associated with that scene is closed, the instances created in that context space disappear, and
62-
destroying a GameObject with context similarly closes the context.
63-
Context spaces are automatically structured by the framework, and parent-child relationships are formed when multiple contexts are loaded.
83+
Doinject defines context scopes that naturally align with Unity's object lifecycle:
84+
* **Project Context:** Lives for the entire application duration.
85+
* **Scene Context:** Tied to a specific scene's lifetime. When the scene is unloaded, the context and its associated instances are disposed.
86+
* **GameObject Context:** Tied to a specific GameObject's lifetime. When the GameObject is destroyed, the context and its instances are disposed.
87+
These contexts automatically form parent-child relationships (e.g., Scene Context inherits from Project Context), allowing dependencies to be resolved hierarchically.
6488

89+
### Integration with the Addressable Asset System
6590

66-
### Collaboration with the Addressable Asset System
91+
Doinject seamlessly integrates with Unity's Addressable Asset System.
92+
You can bind Addressable assets directly, and Doinject will automatically handle loading the asset asynchronously when needed and releasing its handle when the associated context is disposed. This simplifies resource management significantly compared to manual handle tracking.
6793

68-
Instances from the Addressable Asset System can also be handled, and the release of load handles can be automated.
69-
Resource management in Addressables requires careful implementation, such as creating your own resource management system.
70-
However, using Doinject automates the loading and release of Addressables.
94+
### Simplified Dependency Patterns
7195

72-
### Simple coding
73-
74-
You can achieve replacements for the factory pattern, (context-closed) singleton pattern, and service locator pattern with simple descriptions.
75-
Additionally, by creating custom factories or custom resolvers, you can handle more complex instance creation scenarios.
96+
Doinject simplifies the implementation of common dependency management patterns:
97+
* **Factory Pattern:** Easily bind factories for creating instances on demand.
98+
* **Singleton Pattern:** Bind objects as singletons scoped to their context (Project, Scene, or GameObject).
99+
* **Service Locator:** While DI is generally preferred, Doinject can be used to manage globally or locally accessible services.
100+
Custom factories and resolvers offer further flexibility for complex instantiation logic.
76101

77102

78103
## Binding
79104

80105
### Type Binding
81106

82-
| Code | Resolver behavior  | Type |
107+
| Code | Resolver Behavior | Type |
83108
|-----------------------------------------------------------------------|-----------------------------------------|-----------|
84109
| ```container.Bind<SomeClass>();``` | ```new SomeClass()``` | cached |
85-
| ```container.Bind<SomeClass>().AsSingleton();```  | ```new SomeClass()``` | singleton |
86-
| ```container.Bind<SomeClass>().AsTransient();```  | ```new SomeClass()``` | transient |
87-
| ```container.Bind<SomeClass>().Args(123,"ABC");```  | ```new SomeClass(123, "abc")``` | cached |
88-
| ```container.Bind<ISomeInterface>().To<SomeClass>();```  | ```new SomeClass() as ISomeInterface``` | cached |
89-
| ```container.Bind<ISomeInterface, SomeClass>();```  | ```new SomeClass() as ISomeInterface``` | cached |
110+
| ```container.Bind<SomeClass>().AsSingleton();``` | ```new SomeClass()``` | singleton |
111+
| ```container.Bind<SomeClass>().AsTransient();``` | ```new SomeClass()``` | transient |
112+
| ```container.Bind<SomeClass>().Args(123,"ABC");``` | ```new SomeClass(123, "abc")``` | cached |
113+
| ```container.Bind<ISomeInterface>().To<SomeClass>();``` | ```new SomeClass() as ISomeInterface``` | cached |
114+
| ```container.Bind<ISomeInterface, SomeClass>();``` | ```new SomeClass() as ISomeInterface``` | cached |
90115
| ```container.Bind<SomeClass>()```<br />```.FromInstance(instance);``` | ```instance``` | instance |
91116
| ```container.BindInstance(instance);``` | ```instance``` | instance |
92117

118+
**Binding Lifetimes:**
119+
120+
* **`cached` (Default):** Creates an instance on the first resolution within its container and reuses that same instance for subsequent requests within that container. The instance is disposed (if `IDisposable` or `IAsyncDisposable`) when the container is disposed.
121+
* **`singleton`:** Creates a globally unique instance on first resolution. This instance persists for the application's lifetime (or until manually disposed) and is shared across all containers. Use with caution.
122+
* **`transient`:** Creates a new instance every time it is resolved. Doinject does not manage the lifecycle (creation/disposal) of transient instances beyond initial creation; manual disposal might be necessary.
123+
* **`instance`:** Binds a pre-existing instance to the container. Doinject does not manage the lifecycle (creation/disposal) of this instance.
124+
93125
### MonoBehaviour Binding
94126

95-
| Code | Resolver behavior  |
127+
| Code | Resolver Behavior |
96128
|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|
97129
| ```container.Bind<SomeComponent>();``` | ```new GameObject().AddComponent<SomeComponent>()``` |
98130
| ```container```<br />```.Bind<SomeComponent>()```<br />```.Under(transform);``` | ```var instance = new GameObject().AddComponent<SomeComponent>();```<br/>```instance.transform.SetParent(transform);``` |
@@ -101,31 +133,30 @@ Additionally, by creating custom factories or custom resolvers, you can handle m
101133

102134
### Addressables Binding
103135

104-
105-
| Code | Resolver behavior  |
136+
| Code | Resolver Behavior |
106137
|--------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
107-
| ```container```<br />```.BindAssetReference<SomeAddressalbesObject>(assetReference);``` | ```var handle = Addressables```<br />```.LoadAssetAsync<GameObject>(assetReference)```<br/><br/>```await handle.Task```  |
138+
| ```container```<br />```.BindAssetReference<SomeAddressableObject>(assetReference);``` | ```var handle = Addressables```<br />```.LoadAssetAsync<GameObject>(assetReference)```<br/><br/>```await handle.Task``` |
108139
| ```container```<br />```.BindPrefabAssetReference<SomeComponent>(prefabAssetReference);``` | ```var handle = Addressables```<br />```.LoadAssetAsync<GameObject>(prefabAssetReference)```<br/><br/>```var prefab = await handle.Task```<br/><br/>```Instantiate(prefab).GetComponent<SomeComponent>()``` |
109-
| ```container```<br />```.BindAssetRuntimeKey<SomeAddressalbesObject>("guid or path");``` | ```var handle = Addressables```<br />```.LoadAssetAsync<GameObject>("guid or path")```<br/><br/>```await handle.Task```  |
140+
| ```container```<br />```.BindAssetRuntimeKey<SomeAddressableObject>("guid or path");``` | ```var handle = Addressables```<br />```.LoadAssetAsync<GameObject>("guid or path")```<br/><br/>```await handle.Task```  |
110141
| ```container```<br />```.BindPrefabAssetRuntimeKey<SomeComponent>("guid or path");``` | ```var handle = Addressables```<br />```.LoadAssetAsync<GameObject>("guid or path")```<br/><br/>```var prefab = await handle.Task```<br/><br/>```Instantiate(prefab).GetComponent<SomeComponent>()``` |
111142

112143
### Factory Binding
113144

114-
| Code | Resolver behavior  |
145+
| Code | Resolver Behavior |
115146
|-----------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
116147
| ```container```<br />```.Bind<SomeClass>()```<br />```.AsFactory();``` | ```var resolver = new TypeResolver<SomeClass>()```<br/><br/>```new Factory<SomeClass>(resolver) as IFactory<SomeClass>``` |
117148
| ```container```<br />```.Bind<SomeComponent>()```<br />```.AsFactory();``` | ```var resolver = new MonoBehaviourResolver<SomeComponent>()```<br/><br/>```new Factory<SomeComponent>(resolver))```<br />``` as IFactory<SomeComponent>``` |
118149
| ```container```<br />```.Bind<SomeClass>()```<br />```.AsCustomFactory<MyFactory>();``` | ```new CustomFactoryResolver<MyFactory>() as IFactory<SomeClass>``` |
119150

120151

121-
Can also be combined with Addressables.
122-
You can also create a factory that instantiates the asynchronously loaded prefab and calls GetComponent<T>() on it.
123-
```
152+
Factory bindings can also be combined with Addressables.
153+
For example, you can create a factory that asynchronously loads a prefab via Addressables, instantiates it, and returns a specific component:
154+
```cs
124155
container
125156
.BindAssetReference<SomeComponentOnAddressalbesPrefab>(assetReference)
126157
.AsFactory<SomeComponentOnAddressalbesPrefab>();
127158
```
128-
```
159+
```cs
129160
[Inject]
130161
void Construct(IFactory<SomeComponentOnAddressalbesPrefab> factory)
131162
{
@@ -170,15 +201,26 @@ class ExampleClass
170201
}
171202
```
172203

173-
### Injection to MonoBehaviour
204+
### Injection into MonoBehaviours
205+
206+
To enable injection into a `MonoBehaviour`, it must implement the `IInjectableComponent` interface. Dependencies can then be injected via constructor (if applicable) or method injection.
174207

175208
```cs
176-
// Inherits IInjectableComponent
177-
class ExampleComponent : MonoBehaviour, IInjectableComponent
209+
using UnityEngine;
210+
using Doinject;
211+
212+
// Inherit from MonoBehaviour and implement IInjectableComponent
213+
public class ExampleComponent : MonoBehaviour, IInjectableComponent
178214
{
179-
// Method Injection
215+
private SomeClass _someClassDependency;
216+
217+
// Method Injection using [Inject] attribute
180218
[Inject]
181219
public void Construct(SomeClass someClass)
182-
{ ... }
220+
{
221+
_someClassDependency = someClass;
222+
// ... use the dependency
223+
}
183224
}
184225
```
226+
The container automatically finds and calls methods marked with `[Inject]` on components that implement `IInjectableComponent` within its context scope after the component is enabled.

README_ja.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@ Asynchronous DI Container for Unity
77
![](https://img.shields.io/badge/unity-2023.2%20or%20later-green?logo=unity)
88
[![](https://img.shields.io/badge/license-MIT-blue)](https://github.com/mewlist/MewAssets/blob/main/LICENSE)
99

10+
## 目次
11+
12+
- [ドキュメント](#ドキュメント)
13+
- [サンプルプロジェクト](#サンプルプロジェクト)
14+
- [インストール](#インストール)
15+
- [Unity Package Manager でインストール](#unity-package-manager-でインストール)
16+
- [Doinject について](#doinject-について)
17+
- [コンセプト](#コンセプト)
18+
- [非同期DIコンテナ](#非同期diコンテナ)
19+
- [Unity のライフサイクルと矛盾しないコンテクスト空間](#unity-のライフサイクルと矛盾しないコンテクスト空間)
20+
- [Addressable Asset System との連携](#addressable-asset-system-との連携)
21+
- [平易な記述](#平易な記述)
22+
- [バインド記述](#バインド記述)
23+
- [型バインディング](#型バインディング)
24+
- [MonoBehaviour バインディング](#monobehaviour-バインディング)
25+
- [Addressables バインディング](#addressables-バインディング)
26+
- [ファクトリバインディング](#ファクトリバインディング)
27+
- [インジェクション記述](#インジェクション記述)
28+
- [インストーラー](#インストーラー)
29+
- [コンストラクタインジェクション](#コンストラクタインジェクション)
30+
- [メソッドインジェクション](#メソッドインジェクション)
31+
- [MonoBehaviour へのインジェクション](#monobehaviour-へのインジェクション)
32+
1033
## ドキュメント
1134

1235
* [日本語ドキュメント](https://mewlist.github.io/Doinject)
@@ -83,6 +106,13 @@ Doinject を使うと、Addressables のロード・解放を勝手にやって
83106
| ```container.Bind<SomeClass>()```<br />```.FromInstance(instance);``` | ```instance``` | instance |
84107
| ```container.BindInstance(instance);``` | ```instance``` | instance |
85108

109+
**提供タイプ(ライフタイム)について:**
110+
111+
* **cached (デフォルト):** コンテナ内で最初に解決されたときにインスタンスが生成され、以降はそのインスタンスが再利用されます。コンテナが破棄されるとインスタンスも破棄(`IDisposable``IAsyncDisposable` を実装していれば `Dispose`/`DisposeAsync` が呼ばれる)されます。
112+
* **singleton:** グローバルなシングルトン。最初に解決されたときにインスタンスが生成され、アプリケーション終了まで(または明示的に破棄されるまで)単一のインスタンスが維持されます。コンテナを跨いで共有されます。
113+
* **transient:** 解決されるたびに新しいインスタンスが生成されます。インスタンスのライフサイクル管理は Doinject の管理外となります(手動での破棄が必要です)。
114+
* **instance:** 既存のインスタンスをバインドします。コンテナはそのインスタンスの生成や破棄に関与しません。
115+
86116
### MonoBehaviour バインディング
87117

88118
| 記述 | リゾルバの動作  |
@@ -111,12 +141,12 @@ Doinject を使うと、Addressables のロード・解放を勝手にやって
111141

112142
Adressables と組み合わせることも可能です。
113143
非同期ロードしたプレハブを Instantiate し GetComponent<T>() を行うファクトリを作ることもできます。
114-
```
144+
```cs
115145
container
116146
.BindAssetReference<SomeComponentOnAddressalbesPrefab>(assetReference)
117147
.AsFactory<SomeComponentOnAddressalbesPrefab>();
118148
```
119-
```
149+
```cs
120150
[Inject]
121151
void Construct(IFactory<SomeComponentOnAddressalbesPrefab> factory)
122152
{

0 commit comments

Comments
 (0)