Injector
public class Injector : Singleton<Injector>
A lightweight runtime dependency injection (DI) system tailored for Unity, supporting [Inject] and [Provide] attributes. The Injector finds and resolves dependencies via reflection at runtime startup, simplifying cross-component references and modular game architecture.
If you wish to inject after the first-time setup of the Injector during runtime, derive from ISelfRegisteredInjectionTarget and call Injector.CollectSelfRegisteredInjectable(this) in your Awake() method.
Overview
- Purpose: Automatically inject dependencies into
MonoBehaviourcomponents marked with[Inject], and collect dependencies fromIDependencyProvidermethods marked with[Provide]. - Lifecycle: Executes early via
DefaultExecutionOrder(-3000)to ensure dependencies are wired before most game logic begins.
Attributes
InjectAttribute
Usage: Apply to fields or methods.
Target: Field, Method
Purpose: Declares a dependency that should be automatically resolved and injected at runtime.
ProvideAttribute
Usage: Apply to methods.
Target: Method
Purpose: Registers the returned value as a resolvable dependency in the injection registry.
Interfaces
IDependencyProvider
Marker interface to identify provider MonoBehaviours containing [Provide] methods.
IInjectorReceivable
Components implementing this interface will have their InjectionCompleted() method called after all injections are performed.
Functionality
Initialization (Awake)
- Scans scene for all
MonoBehaviours implementingIDependencyProvider. - Registers each
[Provide]method's return value into a DI registry. - Injects all
[Inject]fields and methods for discovered components. - Queues and injects any
ISelfRegisteredInjectionTargetcollected pre-initialization.
Injection Logic (Inject)
- Resolves and assigns instances to fields marked with
[Inject]. - Invokes methods marked with
[Inject], passing resolved arguments. - Calls
InjectionCompleted()on anyIInjectorReceivable.
Public Methods
CollectSelfRegisteredInjectable(ISelfRegisteredInjectionTarget target)
Adds a component to the injection queue if injection hasn’t started yet, otherwise injects immediately.
Internal Mechanics
- Binding Flags: Uses
BindingFlags.Instance | Public | NonPublicto access all eligible fields/methods. - Resolution: Matches field/method parameter types against the internal registry of provided instances.
Dependencies & Integration
- Designed to work seamlessly with GameStateManager, where
[Inject]is used to resolveMultiplayerService,GameServiceFactory, and more.
Usage Example
[Inject]
private MultiplayerService _multiplayer;
[Inject]
void Init(GameServiceFactory factory)
{
_factory = factory;
}
[Provide]
public GameOrchestrator GetGameOrchestrator() => orchestrator;
Hook this into your architecture and your MonoBehaviours will magically receive what they need—no more FindObjectOfType() spaghetti!