Asynchronous DI Container for Unity
Install via Unity Package Manager Please install the packages in the following order:
https://github.com/mewlist/MewCore.git
https://github.com/mewlist/Doinject.git
Doinject is an asynchronous DI (Dependency Injection) framework for Unity.
The concept of asynchronous DI containers is the starting point. Unity 2022 LTS / 2023.2 are supported.
The framework supports the creation and release of asynchronous instances. This allows handling instances through the Addressables Asset Systems as well. Moreover, you can delegate the creation of time-consuming instances to custom factories.
Designed to define context spaces in a way that does not conflict with Unity's lifecycle. When a scene is closed, the context associated with that scene is closed, the instances created in that context space disappear, and destroying a GameObject with context similarly closes the context. Context spaces are automatically structured by the framework, and parent-child relationships are formed when multiple contexts are loaded.
Instances from the Addressable Asset System can also be handled, and the release of load handles can be automated. Resource management in Addressables requires careful implementation, such as creating your own resource management system. However, using Doinject automates the loading and release of Addressables.
You can achieve replacements for the factory pattern, (context-closed) singleton pattern, and service locator pattern with simple descriptions. Additionally, by creating custom factories or custom resolvers, you can handle more complex instance creation scenarios.
Code | Resolver behavior | Type |
---|---|---|
container.Bind<SomeClass>(); |
new SomeClass() |
cached |
container.Bind<SomeClass>().AsSingleton(); |
new SomeClass() |
singleton |
container.Bind<SomeClass>().AsTransient(); |
new SomeClass() |
transient |
container.Bind<SomeClass>().Args(123,"ABC"); |
new SomeClass(123, "abc") |
cached |
container.Bind<ISomeInterface>().To<SomeClass>(); |
new SomeClass() as ISomeInterface |
cached |
container.Bind<ISomeInterface, SomeClass>(); |
new SomeClass() as ISomeInterface |
cached |
container.Bind<SomeClass>() .FromInstance(instance); |
instance |
instance |
container.BindInstance(instance); |
instance |
instance |
Code | Resolver behavior |
---|---|
container.Bind<SomeComponent>(); |
new GameObject().AddComponent<SomeComponent>() |
container .Bind<SomeComponent>() .Under(transform); |
var instance = new GameObject().AddComponent<SomeComponent>(); instance.transform.SetParent(transform); |
container .Bind<SomeComponent>() .On(gameObject); |
gameObject.AddComponent<SomeComponent>() |
container .BindPrefab<SomeComponent>(somePrefab); |
Instantiate(somePrefab).GetComponent<SomeComponent>() |
Code | Resolver behavior |
---|---|
container .BindAssetReference<SomeAddressalbesObject>(assetReference); |
var handle = Addressables .LoadAssetAsync<GameObject>(assetReference) await handle.Task |
container .BindPrefabAssetReference<SomeComponent>(prefabAssetReference); |
var handle = Addressables .LoadAssetAsync<GameObject>(prefabAssetReference) var prefab = await handle.Task Instantiate(prefab).GetComponent<SomeComponent>() |
container .BindAssetRuntimeKey<SomeAddressalbesObject>("guid or path"); |
var handle = Addressables .LoadAssetAsync<GameObject>("guid or path") await handle.Task |
container .BindPrefabAssetRuntimeKey<SomeComponent>("guid or path"); |
var handle = Addressables .LoadAssetAsync<GameObject>("guid or path") var prefab = await handle.Task Instantiate(prefab).GetComponent<SomeComponent>() |
Code | Resolver behavior |
---|---|
container .Bind<SomeClass>() .AsFactory(); |
var resolver = new TypeResolver<SomeClass>() new Factory<SomeClass>(resolver) as IFactory<SomeClass> |
container .Bind<SomeComponent>() .AsFactory(); |
var resolver = new MonoBehaviourResolver<SomeComponent>() new Factory<SomeComponent>(resolver)) as IFactory<SomeComponent> |
container .Bind<SomeClass>() .AsCustomFactory<MyFactory>(); |
new CustomFactoryResolver<MyFactory>() as IFactory<SomeClass> |
public class SomeInstaller : BindingInstallerScriptableObject
{
public override void Install(DIContainer container, IContextArg contextArg)
{
container.Bind<SomeClass>();
}
}
class ExampleClass
{
// Constructor Injection
public ExampleClass(SomeClass someClass)
{ ... }
}
class ExampleClass
{
// Method Injection
[Inject]
public Construct(SomeClass someClass)
{ ... }
}
// Inherits IInjectableComponent
class ExampleComponent : MonoBehaviour, IInjectableComponent
{
// Method Injection
[Inject]
public void Construct(SomeClass someClass)
{ ... }
}