A minimalistic and lightweight Dependency Injection (DI) framework for Unity, inspired by Zenject. MInject is designed to offer a clean, attribute-based injection system and a decoupled signal bus without the performance overhead or complexity of larger frameworks.
- Attribute-Based Injection: Simply mark fields or properties with
[Inject]to resolve dependencies. - Hierarchical Contexts: Supports
ProjectContext(Global) andSceneContext(Local) for scoped dependency resolution. - Signal Bus System: Built-in event aggregation system to decouple sender and receiver logic.
- Flexible Binding: Bind interfaces to concrete implementations via
MonoInstallerorScriptableInstaller. - Zero Boilerplate: No complex setup wizards; just drop the context prefab and start binding.
Create your interface and the class that implements it.
public interface IAudioService
{
void PlaySound(string clipName);
}
public class AudioService : IAudioService
{
public void PlaySound(string clipName)
{
Debug.Log($"Playing: {clipName}");
}
}Inherit from MonoInstallerBase to map your interfaces to your classes.
using MInject;
public class GameInstaller : MonoInstallerBase
{
public override void InstallBindings()
{
// Bind the interface to the concrete instance
Container.Bind<IAudioService>(new AudioService());
// Declare a Signal (Event) used in the scene
Container.DeclareSignal<LevelStartSignal>();
}
}Note: Attach this script to a GameObject in your scene.
- Create an empty GameObject in your scene (e.g., "SceneContext").
- Add the
SceneContextcomponent (included in MInject) to it. - Attach your
GameInstallerscript to the same GameObject.
Add the [Inject] attribute to any MonoBehaviour. MInject automatically resolves dependencies before Start().
using MInject;
using UnityEngine;
public class Player : MonoBehaviour
{
// Dependency is automatically injected
[Inject] private IAudioService _audioService;
[Inject] private SignalBus _signalBus;
private void Start()
{
// Use the service
_audioService.PlaySound("Jump");
// Fire a signal
_signalBus.Fire(new LevelStartSignal());
}
}