You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Doinject is an asynchronous DI (Dependency Injection) framework for Unity.
63
+
Doinject is an asynchronous Dependency Injection (DI) framework for Unity.
42
64
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.
45
67
46
68
## Concepts
47
69
48
70
### Asynchronous DI Containers
49
71
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.
52
74
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.
57
80
58
-
### Context Space Consistent with Unity's Lifecycle
81
+
### Context Scopes Aligned with Unity's Lifecycle
59
82
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.
64
88
89
+
### Integration with the Addressable Asset System
65
90
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.
67
93
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
71
95
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.
***`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.
|```container```<br />```.Bind<SomeClass>()```<br />```.AsFactory();```|```var resolver = new TypeResolver<SomeClass>()```<br/><br/>```new Factory<SomeClass>(resolver) as IFactory<SomeClass>```|
117
148
|```container```<br />```.Bind<SomeComponent>()```<br />```.AsFactory();```|```var resolver = new MonoBehaviourResolver<SomeComponent>()```<br/><br/>```new Factory<SomeComponent>(resolver))```<br />``` as IFactory<SomeComponent>```|
118
149
|```container```<br />```.Bind<SomeClass>()```<br />```.AsCustomFactory<MyFactory>();```|```new CustomFactoryResolver<MyFactory>() as IFactory<SomeClass>```|
119
150
120
151
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:
To enable injection into a `MonoBehaviour`, it must implement the `IInjectableComponent` interface. Dependencies can then be injected via constructor (if applicable) or method injection.
The container automatically finds and calls methods marked with `[Inject]` on components that implement `IInjectableComponent` within its context scope after the component is enabled.
0 commit comments