Global Services
[Service]
public class SomeService { }
Service Initializer
ServiceInitializer<TService...> base class and add the [Service] attribute to it instead:[Service(typeof(SomeService))]
class SomeServiceInitializer : ServiceInitializer<SomeService> { }
[Service(typeof(Cinemachine), SceneName = "Services")]
class CinemachineInitializer : ServiceInitializer<Cinemachine> { }
InitTarget method to provide custom code for resolving the instance.[Service(typeof(SomeSingleton), LazyInit = true)]
class SomeSingletonInitializer : ServiceInitializer<SomeSingleton>
{
public override SomeSingleton InitTarget() => SomeSingleton.Instance;
}
[Service(typeof(SomeSingleton), LazyInit = true)]
class SomeSingletonInitializer : ServiceInitializer<SomeSingleton, SomeSingletonSettings>
{
public override SomeSingleton InitTarget(SomeSingletonSettings settings)
{
var instance = SomeSingleton.Instance;
instance.Settings = settings;
return instance;
}
}
If you need to access some other objects which are not global services in order to initialize the global service, you can also make the service initializer derive from ScriptableObject or MonoBehaviour, and make it implement a IServiceInitializer<TService...> interface. You could then use serialized fields (including Any<TValue> fields for extended functionality) to assign any dependencies you need using the Inspector window, and use the properties of the [Service] attribute to tell Init(args) how it should locate the service initializer:
[CreateAssetMenu]
[Service(typeof(SomeSingleton), ResourcePath = "SomeSingletonInitializer")]
class SomeSingletonInitializer : ScriptableObject, IServiceInitializer<SomeSingleton>
{
[SerializeField] SomeSingletonSettings settings;
public override SomeSingleton InitTarget()
{
var instance = SomeSingleton.Instance;
instance.Settings = settings;
return instance;
}
}
Service Initializer Async
If acquiring the third-party service might not complete immediately, you can also derive from ServiceInitializerAsync<TService...>:
[Service(typeof(SomeService), LoadAsync = true)]
class SomeServiceInitializer : ServiceInitializerAsync<SomeService>
{
public override async Task<SomeService> InitTargetAsync()
{
var loadService = Resources.LoadAsync<GameObject>("SomeService");
await loadService;
var service = ((GameObject)loadService.asset).GetComponent<SomeService>();
var loadDependency = Resources.LoadAsync<GameObject>("SomeDependency");
await loadDependency;
service.Dependency = ((GameObject)loadDependency.asset).GetComponent<SomeDependency>();
return service;
}
}
Local Services
If you have a third-party object that you want to automatically pass to some clients, but they do not exist for the entirely lifetime of the application, then you can register them as local services instead.
Registering local services from third-party assets works exactly the same way as it does with types that you own: using a Service Tag or a Services component.

If you need to register a plain old C# object as a local service, you can use a Wrapper, and then attach the Service Tag to the Wrapper, or drag-and-drop the Wrapper into a Services component.
If you need to register a local service from a third-party object that only becomes available at runtime, you can create a Value Provider that locates the object, and drag-and-drop the Value Provider into a Services component.
Manual
If all else fails, you can also register third-party objects as global or local services manually in code using Service.Set or Service.AddFor respectively.
One downside with this approach, though, is that then Init(args) won’t know anything about those services existing in Edit Mode. This means that:
- The Null Argument Guard can warn you about those services being missing, even if they are going to be available at runtime.
- You won’t be able to use click-to-ping in the Inspector to easily locate these services via their clients.
- These services won’t have a
(Service)label in their header in the Inspector in Edit Mode.
To resolve the first problem, you can attach an Initializer to clients and select Wait For Service from the dropdown of those services.
