Skip to main content
Applies to: Molca Core

Overview

This recipe shows you how to use the [Inject] attribute to access RuntimeManager services (like EventDispatcher, DataManager, ReferenceManager) in your custom MonoBehaviour components. Dependency injection eliminates the need for singleton patterns or manual service lookups, making your code cleaner and more testable. You’ll learn how to inject services into scene objects and runtime-created objects.

Prerequisites

Step-by-step

Step 1: Add [Inject] attribute to service fields

Mark service fields with the [Inject] attribute. The RuntimeManager will automatically populate these fields after initialization.
Why this works: The RuntimeManager scans all scene MonoBehaviour components after initialization and fills fields marked with [Inject]. The Required parameter controls whether a missing service logs an error (default: true).

Step 2: Wait for RuntimeManager initialization

Always call await RuntimeManager.WaitForInitialization() in Start before using injected services. Injected fields are null in Awake and early Start.
Why this works: RuntimeManager.WaitForInitialization() blocks until RuntimeManager.IsReady is true, which happens after all subsystems are initialized and scene injection is complete.

Step 3: Inject dependencies into runtime-created objects

Objects created with Instantiate or AddComponent don’t get automatic injection. Call RuntimeManager.InjectDependencies() manually after creating them.
Why this works: The automatic scene injection pass only runs once during RuntimeManager initialization. Runtime-created objects must call InjectDependencies() explicitly to populate their [Inject] fields.

Step 4: Use InjectDependencies pattern for late initialization

If your component might be created before RuntimeManager is ready, use the InjectDependencies pattern to handle both cases.
Why this works: This pattern handles both scene objects (which get automatic injection) and runtime-created objects (which need manual injection). The null check ensures injection happens exactly once.

Complete example

Here’s a complete example showing dependency injection in a custom training step that uses multiple services:
This step demonstrates:
  • Injecting multiple services (EventDispatcher, ReferenceManager)
  • Waiting for initialization in Start
  • Using injected services in lifecycle methods
  • Proper cleanup in OnStepDeactivated

Troubleshooting

  • Injected fields are null: Ensure you call await RuntimeManager.WaitForInitialization() before accessing injected services. Fields are null until the injection pass completes.
  • Runtime-created objects have null fields: Objects created with Instantiate or AddComponent don’t get automatic injection. Call RuntimeManager.InjectDependencies(instance) after creating them.
  • “Service not registered” error: The service you’re trying to inject isn’t registered with RuntimeManager. Check that the corresponding RuntimeSubsystem is attached to the RuntimeManager prefab and enabled.
  • Injection works in Editor but not in build: Verify that the RuntimeManager prefab is referenced in Molca Project Settings and that the prefab is included in the build.
  • Multiple injection calls cause issues: Calling InjectDependencies() multiple times on the same object is safe — it will re-inject fields but won’t cause errors.