A flexible and powerful dependency injection and service locator system for Unity. This package provides a robust dependency injection system with support for global, scene-specific, and hierarchical service resolution, automatic dependency injection via [Inject] attribute, runtime dependency injection with event bus, configurable exception handling, and comprehensive configuration management, making it easy to manage dependencies across your Unity project.
- Global & Scene Services β Register services globally or per-scene with automatic lifecycle management
- Hierarchical Resolution β Services resolve through parent hierarchy, scene, and global locators automatically
- Automatic Dependency Injection β Use
[Inject]attribute for automatic field and property injection via reflection - Runtime Dependency Injection β Components automatically receive services when they become available at runtime
- Configurable Error Handling β Choose between warning mode or exception mode for injection errors
- Configuration System β Centralized settings via ScriptableObject config and Settings window
- Update Integration β Register services that need
Update(),FixedUpdate(), orLateUpdate()callbacks - Lifecycle Management β Automatic cleanup with
IDestroyableinterface support - Type-Safe β Strongly-typed service registration and retrieval
- Zero Configuration β Works out of the box with minimal setup
- Editor Integration β Quick creation via Unity menu items and Settings window
- Open Window β Package Manager
- Click the + button β Add package from git URL
- Enter the repository URL:
https://github.com/AtaYanki/OmniServio.git
- Wait for Unity to download and import the package
Requirements:
- Unity 6000.0 or newer
OmniServio combines the Service Locator pattern with automatic dependency injection. It provides a centralized registry for dependencies, allowing components to request services without knowing their concrete implementations. This package implements three levels of service resolution:
- Parent Hierarchy β Checks parent GameObjects for OmniServio components
- Scene Level β Falls back to scene-specific OmniServio
- Global Level β Finally checks the global OmniServio
This hierarchy ensures services are resolved from the most specific to the most general context.
public interface IAudioService
{
void PlaySound(string soundName);
}
public class AudioService : IAudioService
{
public void PlaySound(string soundName)
{
Debug.Log($"Playing sound: {soundName}");
}
}Create a bootstrapper to register your services. You can use either a Global or Scene OmniServio:
Global OmniServio (persists across scenes):
using Omni.Servio;
using UnityEngine;
public class GlobalBootstrapper : OmniServioGlobalBootstrapper
{
protected override void Bootstrap()
{
base.Bootstrap(); // Important: Call base to configure as global
// Register services
OmniServio
.Register<IAudioService>(new AudioService())
.Register<ISaveService>(new SaveService());
}
}Scene OmniServio (per-scene):
using Omni.Servio;
using UnityEngine;
public class SceneBootstrapper : OmniServioSceneBootstrapper
{
protected override void Bootstrap()
{
base.Bootstrap(); // Important: Call base to configure for scene
// Register scene-specific services
OmniServio.Register<IGameplayService>(new GameplayService());
}
}Method 1: Manual Retrieval
using Omni.Servio;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private IAudioService _audioService;
void Start()
{
// Automatically resolves from hierarchy β scene β global
OmniServio.For(this).Get(out _audioService);
}
void OnJump()
{
_audioService?.PlaySound("jump");
}
}Method 2: Automatic Dependency Injection (Recommended)
using Omni.Servio;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[Inject] private IAudioService _audioService;
[Inject] private ISaveService _saveService;
void Start()
{
// Dependencies are automatically injected before Start() is called
// No need to add any components - injection happens automatically!
}
void OnJump()
{
_audioService?.PlaySound("jump");
}
}Automatic injection is handled automatically! When you add a OmniServioSceneBootstrapper or OmniServioGlobalBootstrapper to your scene, a DependencyInjectionManager is automatically created. This manager:
- Runs after all bootstrappers complete (execution order 100)
- Automatically injects dependencies into all MonoBehaviour components in the scene
- Ensures services are registered before injection occurs
No manual setup required! Just:
- Add a bootstrapper to your scene (Global or Scene)
- Register your services in the bootstrapper
- Mark fields/properties with
[Inject]attribute - Dependencies are injected automatically!
OmniServio supports automatic dependency injection using the [Inject] attribute. This eliminates the need for manual service retrieval.
Field Injection:
public class GameManager : MonoBehaviour
{
[Inject] private IAudioService _audioService;
[Inject] private ISaveService _saveService;
// Fields are automatically injected before Start()
}Property Injection:
public class GameManager : MonoBehaviour
{
[Inject] public IAudioService AudioService { get; private set; }
[Inject] public ISaveService SaveService { get; private set; }
}Global Service Injection:
Use UseGlobal = true to always inject from the global OmniServio:
public class ConfigManager : MonoBehaviour
{
[Inject(UseGlobal = true)] private IConfigService _configService;
// Always uses OmniServio.Global, regardless of hierarchy
}Manual Injection:
You can also manually trigger injection:
using Omni.Servio;
public class CustomComponent : MonoBehaviour
{
[Inject] private IAudioService _audioService;
void Awake()
{
// Manually inject dependencies
DependencyInjector.Inject(this);
}
}Services can implement IUpdatable, IFixedUpdatable, or ILateUpdatable to receive Unity update callbacks:
public class GameTimer : IUpdatable
{
private float _time;
public void Update(float deltaTime)
{
_time += deltaTime;
}
public float GetTime() => _time;
}
// Register as updatable
OmniServio.Global.RegisterUpdatable<GameTimer>(new GameTimer());Services can implement IDestroyable to receive cleanup callbacks when the OmniServio is destroyed:
public class NetworkManager : IDestroyable
{
public void Destroy()
{
// Cleanup network connections
Disconnect();
}
}
// Register as destroyable
OmniServio.Global.RegisterDestroyable<NetworkManager>(new NetworkManager());For services that should always be global:
// Register globally
OmniServio.Global.Register<IAudioService>(new AudioService());
// Retrieve globally
OmniServio.Global.Get<IAudioService>(out IAudioService audioService);// Get the OmniServio for a specific scene
OmniServio sceneLocator = OmniServio.ForSceneOf(this);
// Register scene-specific service
sceneLocator.Register<IGameplayService>(new GameplayService());The fluent API allows chaining multiple registrations:
OmniServio.Global
.Register<IAudioService>(new AudioService())
.Register<ISaveService>(new SaveService())
.RegisterUpdatable<GameTimer>(new GameTimer())
.RegisterDestroyable<NetworkManager>(new NetworkManager());For components that need to receive services registered at runtime, inherit from RuntimeInjectable:
using Omni.Servio;
using UnityEngine;
public class MyComponent : RuntimeInjectable
{
[Inject] private IAudioService _audioService;
[Inject(UseGlobal = true)] private IConfigService _configService;
protected override void OnServiceInjected(MemberInfo memberInfo, Type serviceType, object service)
{
// Called when a service is injected at runtime
if (serviceType == typeof(IAudioService))
{
Debug.Log("Audio service is now available!");
}
}
}When a service is registered at runtime:
omniServio.Register(new AudioService());Components inheriting from RuntimeInjectable automatically receive the service when it becomes available.
OmniServio includes a comprehensive configuration system accessible via OmniServio > Config > Settings.
Opening Settings:
- Menu:
OmniServio > Config > Settings - Config is automatically created if it doesn't exist
Configuration Options:
- Exception Handler Mode - Choose Warning (default) or ThrowException mode
- Bootstrap Scene - Assign global bootstrap scene reference
- Auto Load in Editor - Automatically load bootstrap scene when entering Play mode
- Load at Runtime - Load bootstrap scene when game starts (for builds)
Exception Handler Modes:
- Warning - Logs warnings when injection fails, execution continues
- ThrowException - Throws exceptions when injection fails, stops execution
The configuration is stored as a ScriptableObject asset and can be placed in the Resources folder for runtime access.
You can configure exception handling globally via config or per-instance:
Global Configuration (via Config):
// Set in OmniServioConfig asset via Settings window
// All DependencyInjectionManager instances use this by defaultRuntime/
βββ Core/
β βββ OmniServio.cs # Main OmniServio component
β βββ ServiceManager.cs # Core service registry
β βββ OmniServioConfig.cs # Configuration ScriptableObject
β βββ BootstrapSceneLoader.cs # Runtime bootstrap scene loader
βββ DependencyInjection/
β βββ InjectAttribute.cs # [Inject] attribute for DI
β βββ DependencyInjector.cs # Reflection-based injection system
β βββ DependencyInjectionManager.cs # Automatic injection manager (execution order 100)
β βββ RuntimeInjectable.cs # Base class for runtime injection
β βββ ServiceRegistrationEventBus.cs # Event bus for service registration
β βββ IInjectionExceptionHandler.cs # Exception handler interface
β βββ ThrowExceptionHandler.cs # Exception handler (strict mode)
β βββ WarningExceptionHandler.cs # Exception handler (warning mode)
βββ Bootstrapping/
β βββ Bootstrapper.cs # Base bootstrapper classes (execution order -100)
β βββ OmniServioGlobalBootstrapper.cs # Global bootstrapper
β βββ OmniServioSceneBootstrapper.cs # Scene bootstrapper
βββ Lifecycle/
β βββ UpdateManager.cs # Update callback management
β βββ DestroyManager.cs # Lifecycle cleanup management
βββ Extensions/
βββ OmniServioExtensions.cs # Utility extensions
Editor/
βββ OmniServioMenuItems.cs # Unity menu integration
βββ OmniServioSettingsWindow.cs # Settings window
βββ OmniServioConfigEditor.cs # Config asset editor
βββ SceneBootstrapper.cs # Bootstrap scene loader (editor)
Samples/
βββ Scripts/
β βββ SampleServices.cs # Example service interfaces/implementations
β βββ SampleBootstrapper.cs # Example bootstrapper
β βββ SampleConsumer.cs # Example service consumer
Static Properties:
static OmniServio Global { get; }β Access the global OmniServio instance
Static Methods:
static OmniServio For(MonoBehaviour monoBehaviour)β Get OmniServio for a MonoBehaviour (hierarchy β scene β global)static OmniServio ForSceneOf(MonoBehaviour monoBehaviour)β Get OmniServio for a specific scene
Instance Methods:
OmniServio Register<T>(T service)β Register a service by typeOmniServio Register(Type type, object service)β Register a service with explicit typeOmniServio RegisterUpdatable<T>(T service)β Register a service that implementsIUpdatableOmniServio RegisterFixedUpdatable<T>(T service)β Register a service that implementsIFixedUpdatableOmniServio RegisterLateUpdatable<T>(T service)β Register a service that implementsILateUpdatableOmniServio RegisterDestroyable<T>(T service)β Register a service that implementsIDestroyableOmniServio Get<T>(out T service)β Retrieve a service (throws if not found)bool TryGet<T>(out T service)β Try to get a service (returns false if not found)
[Inject]β Attribute to mark fields and properties for automatic injection[Inject(UseGlobal = true)]β Always inject from global OmniServioDependencyInjector.Inject(MonoBehaviour component, OmniServio omniServio = null)β Manually inject dependenciesDependencyInjector.SetExceptionHandler(IInjectionExceptionHandler handler)β Set custom exception handlerDependencyInjectionManagerβ Automatically created by bootstrappers to handle injection (execution order 100)RuntimeInjectableβ Base class for components needing runtime dependency injectionServiceRegistrationEventBusβ Event bus for service registration notifications
OmniServioConfigβ ScriptableObject configuration assetOmniServioConfig.Instanceβ Singleton access to configOmniServioSettingsWindowβ Editor window for configuration (OmniServio > Config > Settings)IInjectionExceptionHandlerβ Interface for custom exception handlersThrowExceptionHandlerβ Exception handler that throws on errorsWarningExceptionHandlerβ Exception handler that logs warnings (default)
IUpdatableβ Implement to receiveUpdate()callbacksIFixedUpdatableβ Implement to receiveFixedUpdate()callbacksILateUpdatableβ Implement to receiveLateUpdate()callbacksIDestroyableβ Implement to receive cleanup callbacks on OmniServio destruction
OmniServioGlobalBootstrapperβ Base class for global service registrationOmniServioSceneBootstrapperβ Base class for scene-specific service registration
- Register in Bootstrappers β Always register services in bootstrapper classes, not in individual components
- Use Interfaces β Register services by interface, not concrete types, for better decoupling
- Global vs Scene β Use global services for cross-scene dependencies (audio, save system), scene services for gameplay-specific logic
- Use
OmniServio.For(this)β This automatically resolves through the hierarchy - Prefer Dependency Injection β Use
[Inject]attribute instead of manual retrieval when possible - Cache References β Store service references in fields rather than retrieving repeatedly
- Null Checks β Always check if services are null before use
- Automatic Injection β Injection happens automatically when bootstrappers are present - no manual setup needed!
- Execution Order β Bootstrappers run first (order -100), then DependencyInjectionManager runs (order 100)
- Private Fields β Use private fields with
[Inject]for encapsulation - Properties β Use properties with
[Inject]if you need public access - Global Services β Use
[Inject(UseGlobal = true)]for services that should always come from global - Manual Injection β Use
DependencyInjector.Inject()for runtime injection scenarios
- Implement IDestroyable β For services that need cleanup (network connections, file handles)
- Use Update Interfaces β Only implement update interfaces if your service truly needs Unity callbacks
- Avoid Circular Dependencies β Design services to avoid depending on each other in cycles
The package includes sample scripts demonstrating:
- Service interface and implementation patterns
- Global and scene bootstrapper setup
- Service consumption in MonoBehaviour components
- Automatic dependency injection with
[Inject]attribute - Update callback integration
- Lifecycle management
To use samples:
- Check the
Samples/folder in the package - Copy sample scripts to your project
- Create GameObjects with bootstrapper components
- Add
AutoInjectComponentto test automatic injection - Test service registration and retrieval
- BREAKING CHANGE: Renamed from ServiceLocator to OmniServio
- Added automatic dependency injection with
[Inject]attribute - Added
DependencyInjectorclass for reflection-based injection - Added
AutoInjectComponentfor automatic injection on Awake - Improved namespace organization
See CHANGELOG.md for full version history.
Issue: Service not found exception
- Ensure the service is registered before it's requested
- Check that you're using the correct OmniServio (global vs scene)
- Verify the service type matches exactly (including generic parameters)
Issue: Dependencies not injected
- Ensure a bootstrapper (
OmniServioSceneBootstrapperorOmniServioGlobalBootstrapper) exists in the scene - Check that
DependencyInjectionManagerwas created (should happen automatically) - Verify services are registered in the bootstrapper before injection occurs
- Verify fields/properties are marked with
[Inject]attribute - Check console for injection warnings
- Ensure execution order: Bootstrappers (-100) β DependencyInjectionManager (100)
Issue: Services not persisting across scenes
- Use
OmniServioGlobalBootstrapperfor cross-scene services - Ensure
dontDestroyOnLoadis set totrueon the global bootstrapper
Issue: Update callbacks not firing
- Verify the service implements
IUpdatable,IFixedUpdatable, orILateUpdatable - Ensure the service is registered using
RegisterUpdatable,RegisterFixedUpdatable, orRegisterLateUpdatable
Issue: Multiple OmniServios in scene
- Only one OmniServio per scene is recommended
- Use the hierarchy system if you need nested service resolution
MIT License - See LICENSE for details.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with clear commit messages
- Submit a pull request
Areas for contribution:
- Additional sample scenes
- Performance improvements
- Bug fixes
- Documentation improvements
Found a bug or have a feature request?
- Open an issue on GitHub
- Provide Unity version, error logs, and reproduction steps
Need help integrating?
- Check the included sample scripts
- Review the Quick Start guide above
- Open a discussion on GitHub
Unity, Dependency Injection, Service Locator, IoC, Design Patterns, Architecture, Services, Global Services, Scene Services, Reflection, Automatic Injection