Service Lifetime & Lifecycle
OneLastClick.Services manages the lifetime of registered services.
A service does not simply appear when it is registered and disappear when its GameObject is destroyed. The service system has an explicit lifecycle that controls when dependencies are injected and when lifecycle callbacks are invoked.
This is especially important for services that implement IService.
Scope Lifetime
Section titled “Scope Lifetime”The lifetime of a service depends on its scope.
Application service
Section titled “Application service”Application starts │ ▼Application Services prefab loaded │ ▼Services registered │ ▼Application continues │ ▼Application endsScene service
Section titled “Scene service”Scene loaded │ ▼Root service components discovered │ ▼Services registered │ ▼Dependencies injected │ ▼Services available │ ▼Scene unloaded │ ▼Services removedScene MonoBehaviour services follow the lifetime of their scene.
You do not need to manually unregister them when the scene is unloaded.
The Service Lifecycle
Section titled “The Service Lifecycle”The lifecycle of a service is:
Register │ ▼Inject Dependencies │ ▼Start │ ▼Update │ │ ... once per frame ... │ ▼Stop │ ▼UnregisterThe important rule is that dependency injection happens before OnServiceStart().
This means a service can safely use its injected dependencies during startup.
IService
Section titled “IService”A service participates in the lifecycle by implementing IService.
public interface IService{ void OnServiceStart(); void OnServiceUpdate(); void OnServiceStop();}All three methods are required.
If a service doesn’t need lifecycle callbacks, it does not need to implement IService.
On Service Start
Section titled “On Service Start”OnServiceStart() is called after the service has been registered and its dependencies have been injected.
This is the appropriate place for service initialization.
[ApplicationService]public partial class GameService : IService{ [InjectService] private SaveService _saveService;
public void OnServiceStart() { _saveService.Load(); }
public void OnServiceUpdate() { }
public void OnServiceStop() { }}At the point OnServiceStart() is called:
- The service has been registered.
- Its
[InjectService]dependencies have been resolved. - The service is ready to begin operating.
Why not initialize in a constructor?
Section titled “Why not initialize in a constructor?”Unity objects, such as MonoBehaviours, can not have a custom constructor. Therefore, the start function can be used as a initialization point for services.
On Service Update
Section titled “On Service Update”OnServiceUpdate() is called once per frame while the service is active.
public void OnServiceUpdate(){ // Called once per frame.}This allows plain C# services to participate in Unity’s frame update without needing to inherit from MonoBehaviour.
For example:
[ApplicationService]public partial class GameTimeService : IService{ public float GameTime { get; private set; }
public void OnServiceStart() { GameTime = 0f; }
public void OnServiceUpdate() { GameTime += Time.deltaTime; }
public void OnServiceStop() { }}MonoBehaviour services can also implement IService. The service lifecycle should be used for service-level behaviour rather than adding a separate Update() simply because the component happens to inherit from MonoBehaviour.
On Service Stop
Section titled “On Service Stop”OnServiceStop() is called when the service’s scope is being stopped.
This is the appropriate place to clean up anything that the service created or subscribed to during its lifetime.
public void OnServiceStop(){ SomeEvent.OnChanged -= OnChanged;}A useful pattern is:
public void OnServiceStart(){ SomeEvent.OnChanged += OnChanged;}
public void OnServiceStop(){ SomeEvent.OnChanged -= OnChanged;}This keeps the service’s subscriptions aligned with its lifetime.
Application Service Lifecycle
Section titled “Application Service Lifecycle”Application services belong to the application scope.
Their lifecycle follows the application service system:
Application Service System Starts │ ▼ Register Services │ ▼ Inject Dependencies │ ▼ OnServiceStart() │ ▼ OnServiceUpdate() │ │ ▼ Application Stops │ ▼ OnServiceStop()Application services therefore remain active across scene changes.
For example:
Application│├── Scene A│├── Scene B│└── Scene CAn application service remains active while the application moves between these scenes.
Scene Service Lifecycle
Section titled “Scene Service Lifecycle”Scene services are tied to the scene that owns them.
Their lifecycle begins when the scene’s services are registered:
Scene Loaded │ ▼Register Scene Services │ ▼Inject Dependencies │ ▼OnServiceStart() │ ▼OnServiceUpdate() │ │ ▼Scene Unloaded │ ▼OnServiceStop()This means a scene service can safely initialize scene-specific systems in OnServiceStart() and clean them up in OnServiceStop().
For example:
[MonoBehaviourService]public partial class LevelService : MonoBehaviour, IService{ public void OnServiceStart() { Debug.Log("Level started"); }
public void OnServiceUpdate() { }
public void OnServiceStop() { Debug.Log("Level stopped"); }}Lifecycle Events
Section titled “Lifecycle Events”The following table summarizes when each lifecycle event occurs.
| Event | Application Service | Scene Service |
|---|---|---|
| Register | Application startup | Scene load |
| Inject | Before start | Before start |
OnServiceStart() |
After registration and injection | After registration and injection |
OnServiceUpdate() |
Once per frame | Once per frame |
OnServiceStop() |
Application service system stops | Scene unload |
| Unregister | After stopping | After stopping |
Play Mode Lifecycle
Section titled “Play Mode Lifecycle”The service lifecycle also applies when entering and leaving Unity Play Mode.
A typical Play Mode session looks like:
Enter Play Mode │ ▼Register Application Services │ ▼Inject Dependencies │ ▼Start Application Services │ ▼Load Scene │ ▼Register Scene Services │ ▼Inject Dependencies │ ▼Start Scene Services │ ▼ Running │ ▼Exit Play Mode │ ▼Stop Scene Services │ ▼Stop Application ServicesThis lifecycle is particularly important when Domain Reload is disabled.
Unity can preserve static state between Play Mode sessions when domain reload is disabled. The service system therefore explicitly manages service startup and shutdown rather than relying on static state being reset.
Services should use OnServiceStart() and OnServiceStop() for lifecycle-dependent work.
Summary
Section titled “Summary”IService provides a consistent lifecycle for both application and scene services.
The lifecycle is:
Register ↓Inject ↓OnServiceStart() ↓OnServiceUpdate() every frame ↓OnServiceStop() ↓UnregisterThe scope determines how long that lifecycle lasts:
- Application services start with the application service scope and stop when that scope ends.
- Scene services start when their scene services are loaded and stop when their scene is unloaded.
Use OnServiceStart() for initialization, OnServiceUpdate() for per-frame processing, and OnServiceStop() for cleanup.