SingletonObject
Abstract generic plain C# singleton that creates its instance via new T(). The simplest singleton variant — no Unity asset backing, no scene presence, no load-from-Resources chain. Automatically subscribes to Application.quitting for cleanup. Extends ParagonObject.
Definition
Namespace: Paragon Assembly: Paragon.dll
[SingletonSettings]
public abstract class SingletonObject<T> : ParagonObject
where T : SingletonObject<T>, new()Inheritance: ParagonObject → SingletonObject<T> Implements (via ParagonObject): IDisposable, IDebugObject
Remarks
SingletonObject<T> is for singletons that don't need Unity scene presence or asset persistence. Its resolution chain on first Instance access:
Return cached — If
instanceis already set, return it.Create —
new T()followed byInitialize().
On Application.quitting, the singleton calls Destroy() (inherited from ParagonObject) and clears the static instance.
Because ParagonObject implements IDisposable (delegating to Destroy()), the singleton's cleanup is also triggered if Dispose() is called, though this is not the typical lifecycle path.
Quick Lookup
Access the singleton
MySingleton.Instance
Define a new singleton
Subclass SingletonObject<T>, add [SingletonSettings], ensure new() constraint
Add custom initialization
Override Initialize(), call base.Initialize()
Add custom cleanup
Override OnDestroy()
Initialize at startup
Set InitializeOnLoad = true in [SingletonSettings]
Properties
Instance
Static accessor for the singleton. Triggers lazy initialization on first access.
Methods
Initialize
Called automatically after new T() during first access. Asserts no duplicate, sets the static instance, and registers the quit callback. Overrides ParagonObject.Initialize().
Always call base.Initialize() when overriding. It sets the instance field and registers the application quit handler.
Extension Points
Optional Overrides
Initialize()
void
First Instance access
Custom setup. Call base.Initialize().
OnDestroy()
void
Application quit
Custom cleanup (inherited from ParagonObject).
OnDebug()
void
Each debug frame
Debug rendering (inherited from ParagonObject).
Implementation Requirements
When subclassing SingletonObject<T>, you MUST:
Apply
[SingletonSettings]to the concrete classUse the CRTP pattern:
class MyService : SingletonObject<MyService>Have a public parameterless constructor (the
new()constraint)Call
base.Initialize()if overridingInitialize()
You SHOULD:
Set
InitializeOnLoad = truefor services needed at startupOverride
OnDestroy()for cleanup of unmanaged resources
Type Parameters
T
SingletonObject<T>, new()
The concrete subclass type (CRTP). Must have a public parameterless constructor.
Common Pitfalls
Duplicate instance assertion Initialize() asserts that instance == null. If you manually create a second instance, the assertion fires. Always access via Instance.
No asset persistence Unlike SingletonBehaviour and SingletonScriptableObject, this singleton has no Unity asset backing. It cannot be configured via the Inspector. Use serialized config files or constants for configuration.
Cleanup happens on Application.quitting The singleton is destroyed during the Application.quitting event. Accessing Instance during or after this event may create a new instance that will not be properly cleaned up.
Examples
Basic Service
See Also
SingletonBehaviour<T> — MonoBehaviour variant
SingletonScriptableObject<T> — ScriptableObject variant
SingletonSettingsAttribute — configuration attribute
SingletonInitializer — startup bootstrap
ParagonObject — base class
Singletons Subsystem — subsystem overview
Last updated