Service Locator
The Service Locator is a global point of access to a service. A service represents a game-wide system or manager that performs a specific function and needs to be available to the entire simulator.
Instead of hard-wiring dependencies between systems, each system requests what it needs from the Service Locator.
At runtime, the Service Locator maintains a registry of all registered services, indexed by their type. Each service can be registered, retrieved, or unregistered dynamically through the API.
Accessing the Locator
The Service Locator is initialized automatically before the first Scene loads. You can access it from any script at runtime, like this:
var locator = UnityServiceLocator.Current;
Creating a Service
To create a service, create a class that implements the IUnityGameService interface.
using UnityEngine;
using mobisim.Core.Service;
public class ExampleService : MonoBehaviour, IUnityGameService
{
public void DoSomething() => Debug.Log("ExampleService is doing something.");
}
Registering a Service
A service must be registered so the locator can find it. Use TryRegister() to register a service:
public class ExampleService : MonoBehaviour, IUnityGameService
{
private void Start()
{
// Returns `false` if a service of the same type is already registered.
if (UnityServiceLocator.Current.TryRegister(this))
{
Debug.Log("ExampleService successfully registered.");
}
}
// ... rest of the service
}
TryRegister() does not allow multiple instances of the same service type to be registered. If a service of that type already exists, the call fails and returns false without replacing it.
If you want to replace an existing registered service of the same type, use:
UnityServiceLocator.Current.ForceRegister(this);
Services are indexed by the generic type argument used when registering. TryRegister(this) registers under the concrete class type, while TryRegister<IMyService>(this) registers under the interface, and the service must then be retrieved with that same type (for example TryGet<IMyService>).
Use ForceRegister with care: it overwrites any existing instance of that service type.
Unregistering a Service
When a service is being destroyed, it should unregister itself. Use TryUnregister() to remove the service from the locator. It only succeeds if the instance you pass is the one currently registered for that type; use ForceUnregister<T>() to remove whatever is registered:
public class ExampleService : MonoBehaviour, IUnityGameService
{
private void OnDestroy()
{
if (UnityServiceLocator.Current.TryUnregister(this))
{
Debug.Log("ExampleService successfully unregistered.");
}
}
// ... rest of the service
}
Retrieving a Service
Once a service is registered, it is accessible anywhere. Use TryGet() to safely retrieve a service by its type (it returns false and logs a warning if the service is not registered):
if (UnityServiceLocator.Current.TryGet<ExampleService>(out var service))
{
service.DoSomething();
}
The locator also provides non-Try variants, Register(), Unregister(), and Get<T>(), which log an error on failure instead of returning false (Get<T>() throws an InvalidOperationException if the service is not registered).