Skip to main content

Injecting into MonoBehaviours

As MonoBehaviours do not support constructors, you must use method injection to inject them with dependencies.

Note that the presence of the [Inject] attribute on a MonoBehaviour's method does not imply that it will automatically be called. You must inject dependencies manually in one of the following three ways:

  1. If you want to inject into a specific MonoBehaviour, you can specify it in the LifetimeScope's inspector.
    • The MonoBehaviours of all specified GameObject (and their children) will be automatically Injected when the LifetimeScope is initialized.
  2. Use one of the RegisterComponent* methods to register the MonoBehaviour instance to the container.
    • In this case, the registered MonoBehaviour will both Inject and be Injected into other classes.
    • See Register MonoBehaviour
  3. To inject into dynamically-generated MonoBehaviours at runtime (e.g. from prefabs), use IObjectResolver.Instantiate instead of UnityEngine.Object.Instantiate. (Factory patterns and object generation expressions can be registered.)

Why doesn't VContainer automatically inject into all MonoBehaviours?#

  • Unity doesn't provide a good way to listen for the creation of all GameObjects or MonoBehaviours. Rather than having some cases that are automatically Injected and some that are not, we decided on explicit Injection that you can use to fit your own needs.
  • We do not recommend excecuting Inject directly on MonoBehaviours; instead, use InjectGameObject on the owning GameObject.
    • MonoBehaviour is a C# class that allows you to write code for anything, also, it is dynamically created/destroyed at runtime. Injection into an object with a dynamic lifetime complicates reference management. The simplest solution to this is to not do it.
    • This is because the purpose of VContainer and DI is inversion of control of MonoBehaviour.
      • View component is often the starting point for detecting events and happenings, but it can also be styled to notify the outside world that it has ownership of the events it detects.
    • If a MonoBehaviour needs an explicit Inject call, you risk losing the advantages of Unity's prefab portability.
    • Of course, in order for the View component to work, it needs to know the data/state to be displayed on the screen, but data that changes rapidly at runtime is not subject to injection by [Inject], and is better handled as mere "values" by arguments.