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:

  1. Return cached — If instance is already set, return it.

  2. Createnew T() followed by Initialize().

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

Goal
How

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().

circle-exclamation

Extension Points

Optional Overrides

Method
Return Type
Called When
Purpose

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:

  1. Apply [SingletonSettings] to the concrete class

  2. Use the CRTP pattern: class MyService : SingletonObject<MyService>

  3. Have a public parameterless constructor (the new() constraint)

  4. Call base.Initialize() if overriding Initialize()

You SHOULD:

  • Set InitializeOnLoad = true for services needed at startup

  • Override OnDestroy() for cleanup of unmanaged resources

Type Parameters

Parameter
Constraint
Description

T

SingletonObject<T>, new()

The concrete subclass type (CRTP). Must have a public parameterless constructor.

Common Pitfalls

circle-exclamation
circle-exclamation
circle-exclamation

Examples

Basic Service

See Also

Last updated