Doinject En 1.0.8 Help

Binding

Registering types or instances with the DI container is called binding.

Instance provision methods
  • Singleton

  • Factory

  • Fixed instance

  • Temporary generation (Transient)

Types of objects
  • Type

  • Game object

  • Prefab

  • Addressable Asset

Other
  • Factory

  • Arguments

By combining these, you can perform various bindings flexibly with simple coding.

Specifying the type to bind

The simplest type binding

container.Bind<SomeClass>();

Register the type SomeClass in the DI container. An instance is created only once in the context space when there is an injection target and is cached (same as AsCached()).

Interface

container.Bind<ISomeInterface>() .To<SomeClass>();

SomeClass needs to implement ISomeInterface. An instance of SomeClass is injected into ISomeInterface.

You can also write it as follows.

container.Bind<ISomeInterface, SomeClass>();

Type inherited from MonoBehaviour

container.Bind<SomeComponent>();

The coding for regular binding is the same.

You can specify the generation position as follows.

  • Generate at the top level of the scene to which the context belongs

    container.Bind<SomeComponent>() .UnderSceneRoot();
  • Generate as a child object of the specified Transfrom

    container.Bind<SomeComponent>() .Under(someTransform);
  • AddComponent to the specified GameObject

    container.Bind<SomeComponent>() .On(someGameObject);

Instance

container .Bind<SomeClass>() .FromInstance(someClassInstance);

someClassInstance is injected as is.

You can also write it as follows.

container.BindInstance(someClassInstance);

Generate an instance from a prefab

container.BindPrefab<SomeComponent>(somePrefab);

SomeComponent needs to be attached to the root object of the prefab.

You can specify the generation position as follows.

  • Generate at the top level of the scene to which the context belongs

    container.Bind<SomeComponent>() .UnderSceneRoot();
  • Generate as a child object of the specified Transfrom

    container.BindPrefab<SomeComponent>(somePrefab) .Under(someTransform);

Load from Addressable Asset

AsserReference is a type provided by the Addressable Asset System and represents a reference to an asset.

AssetReference assetReference = ...; container.BindAssetReference<SomeAddressalbesObject>(assetReference);

You can also specify RuntimeKey directly using BindAssetRuntimeKey.

string path_or_guid_of_asset = ...; container.BindAssetRuntimeKey<SomeAddressalbesObject>(path_or_guid_of_asset);

Load a prefab from Addressables Asset and generate an instance

You can load a prefab from the Addressable Asset System and generate an instance using BindPrefabAssetReference. PrefabAssetReference is a type provided by Doinject for referencing prefabs. SomeComponent needs to be attached to the root object of the prefab.

PrefabAssetReference prefabAssetReference = ...; container.BindPrefabAssetReference<SomeComponent>(prefabAssetReference);

You can also specify RuntimeKey directly using BindPrefabAssetRuntimeKey.

string path_or_guid_of_prefab = ...; container.BindPrefabAssetRuntimeKey<SomeComponent>(path_or_guid_of_prefab);

You can specify the generation position as follows.

  • Generate at the top level of the scene to which the context belongs

    container.BindPrefabAssetReference<SomeComponent>(prefabAssetReference) .UnderSceneRoot();
  • Generate as a child object of the specified Transfrom

    container.BindPrefabAssetReference<SomeComponent>(prefabAssetReference) .Under(someTransform);

Specifying the instance generation method

Cache

container.Bind<SomeClass>() .AsCached();

By calling AsCached(), you explicitly indicate that it will be cached. Even if there is no coding, it is cached by default. You can also write it as follows.

container.BindCached<SomeClass>(); // Abbreviation of the above

Singleton

container.Bind<SomeClass>() .AsSingleton(); container.BindSingleton<SomeClass>(); // Abbreviation of the above

It generates only one instance in the context. Unlike AsCached(), it generates an instance even if there is no injection target.

Temporary (Transient)

container.Bind<SomeClass>() .AsTransient();

Instances generated by AsTransient() are generated separately for each injection target. Since the generated instance may not be automatically destroyed when the DI container is released, care is needed.

Arguments

Assume that SomeClass has the following constructor.

public SomeClass(int someInt, string someString) { ... }

For such types, you need to pass arguments when generating instances, You need to define arguments with Args().

container.Bind<SomeClass>() .Args(123, "some argument string");

Injecting another bound type

Assume that SomeClass has the following constructor.

public SomeClass(ISomeInterface someInterface) { ... }

And, ISomeInterface is bound.

container.Bind<ISomeInterface>() .To<SomeOtherClass>(); container.Bind<SomeClass>();

In this case, when SomeClass is generated, an instance of SomeOtherClass is automatically injected into ISomeInterface.

Next, consider a case with a more complex constructor like the following.

public SomeClass(ISomeInterface someInterface, int someInt, string someString) { ... }

By specifying the arguments that the DI container cannot resolve with Args(), it is possible to generate instances.

container.Bind<ISomeInterface>() .To<SomeOtherClass>(); container.Bind<SomeClass>() .Args(123, "some argument string");

Injection is performed for arguments that the DI container cannot resolve according to the order of arguments specified in Args. Therefore, even for the following constructor, injection is possible without any problem with the above binding description.

public SomeClass(int someInt, ISomeInterface someInterface, string someString) { ... }

Factory

The way to generate a factory is to just call AsFactory() on the binding description. IFactory<T> corresponding to the binding description is automatically bound.

container.Bind<SomeClass>() .AsFactory();

By describing this way, IFactory<SomeClass> is bound.

By defining a factory, a factory that generates the specified instance can be injected. You can generate an instance by calling the CreateAsync() method on the factory instance.

IFactory<SomeClass> factory; ... var instance = await factory.CreateAsync();

To use a factory, inject IFactory<SomeClass> as follows.

public class SomeClass { IFactory<SomeClass> factory; [Inject] async Task Construct(IFactory<SomeClass> factory) { this.factory = factory; // Hold the factory } public async Task Create() { var instance = await factory.CreateAsync(); // Generate an instance at any time } }

You can use the binding syntax shown so far as is, so you can combine them freely to perform various bindings flexibly with simple coding.

Here are some examples.

Factory that returns an interface

container.Bind<ISomeInterface>() .To<SomeClass>() .Args(123, "some argument string") .AsFactory(); // IFacoty<ISomeInterface> is bound. [Inject] async Task Construct(IFacoty<SomeComponent> factory) { ... }

Component factory

container.Bind<SomeComponent>() .On(someGameObject) .AsFactory(); // IFacoty<SomeComponent> is bound. [Inject] async Task Construct(IFacoty<SomeComponent> factory) { ... }

Prefab instance factory

container.BindPrefab<SomeComponent>(somePrefab) .Under(someTransform) .Args(123, "some argument string") .AsFactory(); // IFacoty<SomeComponent> is bound. [Inject] async Task Construct(IFacoty<SomeComponent> factory) { ... }

Addressable Asset prefab instance factory

container.BindPrefabAssetReference<SomeComponent>(prefabAssetReference) .UnderSceneRoot() .Args(123, "some argument string") .AsFactory(); // IFacoty<SomeComponent> is bound. [Inject] async Task Construct(IFacoty<SomeComponent> factory) { ... }
Last modified: 27 December 2024