Skip to content
One Last Click Docs

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.

The lifetime of a service depends on its scope.

Application starts
│
▼
Application Services prefab loaded
│
▼
Services registered
│
▼
Application continues
│
▼
Application ends
Scene loaded
│
▼
Root service components discovered
│
▼
Services registered
│
▼
Dependencies injected
│
▼
Services available
│
▼
Scene unloaded
│
▼
Services removed

Scene MonoBehaviour services follow the lifetime of their scene.

You do not need to manually unregister them when the scene is unloaded.

The lifecycle of a service is:

Register
│
▼
Inject Dependencies
│
▼
Start
│
▼
Update
│
│ ... once per frame ...
│
▼
Stop
│
▼
Unregister

The important rule is that dependency injection happens before OnServiceStart().

This means a service can safely use its injected dependencies during startup.


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.


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:

  1. The service has been registered.
  2. Its [InjectService] dependencies have been resolved.
  3. The service is ready to begin operating.

Unity objects, such as MonoBehaviours, can not have a custom constructor. Therefore, the start function can be used as a initialization point for services.


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.


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 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 C

An application service remains active while the application moves between these scenes.


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");
}
}

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

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 Services

This 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.


IService provides a consistent lifecycle for both application and scene services.

The lifecycle is:

Register
↓
Inject
↓
OnServiceStart()
↓
OnServiceUpdate() every frame
↓
OnServiceStop()
↓
Unregister

The 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.