SingletonInitializer
Internal static utility that runs before the first scene loads to eagerly initialize singletons marked with InitializeOnLoad = true. Scans all Paragon assemblies for concrete types decorated with SingletonSettingsAttribute and triggers their Instance property getter, forcing lazy initialization to complete before any game code runs.
Definition
Namespace: Paragon Assembly: Paragon.dll
internal static class SingletonInitializerRemarks
SingletonInitializer solves the ordering problem where game code might access a singleton in Awake() or Start() before the singleton has been created. By running at RuntimeInitializeLoadType.BeforeSceneLoad, it guarantees that all InitializeOnLoad singletons exist before any MonoBehaviour.Awake() is called.
Initialization Algorithm
Collect all loaded assemblies whose
FullNamestarts with"Paragon".From those assemblies, find all types that:
Are not abstract
Are not generic (open generic types like
SingletonBehaviour<T>are excluded)Have
[SingletonSettings]applied (including inherited)
For each matching type where
InitializeOnLoad == true:Resolve the
Instancestatic property via reflection (BindingFlags.Public | Static | FlattenHierarchy)Call
GetValue(null)— this triggers the lazy initialization chain
Methods
Initialize
Runs before scene load. Scans and initializes all eligible singletons.
This method is called automatically by Unity's runtime initialization system. It should never be called manually.
Common Pitfalls
Only scans Paragon assemblies The initializer filters assemblies by FullName.StartsWith("Paragon"). Singletons defined in assemblies with different names (e.g., game-specific assemblies not prefixed with "Paragon") will not be discovered. In that case, those singletons must be accessed manually before they're needed, or the assembly must use the Paragon naming prefix.
Reflection cost at startup The initializer uses AppDomain.CurrentDomain.GetAssemblies() and GetTypes() on all Paragon assemblies. This is a one-time cost at startup but can be noticeable with many assemblies. The Where filters minimize the work per type.
Open generic types are excluded Types like SingletonBehaviour<T> themselves are skipped (they are abstract and generic). Only concrete, non-abstract subclasses with [SingletonSettings] are initialized.
See Also
SingletonSettingsAttribute — the
InitializeOnLoadflag this class readsSingletonBehaviour<T> — MonoBehaviour singleton variant
SingletonScriptableObject<T> — ScriptableObject singleton variant
SingletonObject<T> — plain C# singleton variant
Singletons Subsystem — subsystem overview
Last updated