Doinject En 1.0.8 Help

Getting Started with Doinject

Installing via Unity Package Manager

You can install it from the Unity Package Manager.

Installing MewCore

First, please install the MewCore package, which is a dependent library.

  1. Select Window > Package Manager from the Unity menu.

  2. Click the + button and select Add package from git URL....

  3. Enter the following and click Add.

    https://github.com/mewlist/MewCore.git
    git@github.com:mewlist/MewCore.git

Installing Doinject

Next, install the Doinject package.

  1. Select Window > Package Manager from the Unity menu.

  2. Click the + button and select Add package from git URL....

  3. Enter the following and click Add.

    https://github.com/mewlist/Doinject.git
    git@github.com:mewlist/Doinject.git

Determining the Entry Point

The first thing to do is to open the scene where you want to apply the DI framework and place the SceneContext component in the hierarchy.

Right-click in the hierarchy view and select the Doinject > Create Scene Context menu.

ContextMenu

Scene context that has been placed

SceneContext.png

Now, this scene functions as an execution environment for the DI framework. Please try playing it once.

SceneContextCreated.png

When the scene is played, various loaders are generated like this.

First Injection

Let's register an instance in the DI container and perform an injection. Instance registration (also known as binding) is done from a component called an installer.

About Injection Points

There are several ways to inject a type registered in the DI container into a specific instance:
  • Constructor Injection

  • Method Injection

  • Field Injection

  • Property Injection

Constructor injection is automatically performed when an instance is created through the DI container. Method injection is performed by calling a method with the [Inject] attribute. Property and field injection inject an instance to a field or property with the [Inject] attribute.

In the case of components that inherit from MonoBehaviour, constructor injection cannot be used. This is because the generation of components is done by Unity, so you cannot explicitly call the constructor. Therefore, you need to use method injection, field injection, or property injection.

Constructor Injection

class SomeClass { // When SomeClass is created, SomeDependency is automatically injected public SomeClass(SomeDependency dependency) { ... } }

Method Injection

class SomeClass { // A method with the [Inject] attribute is called by the DI container after the instance is created, passing SomeDependency as an argument [Inject] public void InjectMethod(SomeDependency dependency) { ... } }

About the OnInjected() Callback

A method (no arguments, public) with the [OnInjected] attribute will automatically be called when the instance's injection is complete. It can also be an asynchronous function with a Task or ValueTask return value.

Especially for components that inherit from MonoBehaviour, the timing of lifecycle methods such as Awake or Start and the timing of injections may be reversed. The [OnInjected] callback is designed to be called on the next frame after the injection is complete, so it can be used to stabilize the initialization order.

class SomeClass { public SomeClass(SomeDependency dependency) { ... } // It is automatically called when the injection of the instance is complete [OnInjected] public void OnInjected() { ... } }

Creating an Installer Script

You can create an installer from the Doinject menu. By right-clicking in the Project view and selecting Create > Doinject > Component Binding Installer C# Script, an installer script is created.

SceneContext

If you create a script named CustomComponentBindingInstallerScript.cs, a script like the following will be created.

using Doinject; public class CustomComponentBindingInstallerScript : BindingInstallerComponent { public override void Install(DIContainer container) { // Bind your dependencies here } }

Also, to verify the operation, we will create an object to register in the DI container and a script to inject as follows.

Player Object

using System; using UnityEngine; [Serializable] public class Player { [SerializeField] public string name; public Player(string name) { this.name = name; } }

Script to Inject

using Doinject; using UnityEngine; public class InjectTargetScript : MonoBehaviour, IInjectableComponent { [SerializeField] private Player player; [Inject] public void Construct(Player player) { this.player = player; } }

The goal is for the instance of the Player object to be injected through InjectTargetScript.Construct().

Now, let's describe the binding in the installer. Bindings are done in the Install method.

public override void Install(DIContainer container) { container .Bind<Player>() .Args("Novice Player") .AsSingleton(); }

.Bind<Player>() is a declaration to get the Player class through the container. .Args("Novice Player") is an argument to pass to the constructor of the Player class. .AsSingleton() indicates that the Player object provided through the container is a singleton.

Bindings are done through a Fluent Interface like this. Depending on how you describe it, you can define flexible behaviors such as acting as a factory or getting instances through an interface.

Now, a Player object, which is unique within the context, has been registered in the DI container.

Finally, let's place the installer in the scene.

Installer placed on scene

Component installers basically function wherever they are placed in the scene. Also, it doesn't matter if there are multiple different installers. It's a good idea to set rules such as placing them under the entry point for clarity.

Checking the Operation

Let's place the InjectTargetScript component we made earlier in the scene.

Inject target placed on scene

Now, let's play the scene.

Inject target injected

You can confirm that the name of the Player is set to "Novice Player".

The argument specified by Args was passed to the constructor of Player (constructor injection), and the Player object was passed to the Construct method of InjectTargetScript (method injection).

Supplement

Objects placed throughout the scene are all covered by the scene context.
  • The scene context, when created, searches for installers belonging to its own context and performs bindings according to their definitions.

  • Once all the installers have completed their bindings, the DIContainer is in a state where it knows the types it should handle and how to resolve instances.

  • After that, the scene context searches for all game objects in the scene and looks for components that implement IInjectableComponent.

  • When a component implementing IInjectableComponent is found, it calls the method with the [Inject] attribute specified on that component to pass an instance that matches the argument and type.

  • The scene context is created in sync with the scene lifecycle and is destroyed along with the instances held by the container when the scene is destroyed.

Last modified: 11 December 2024