singleton property
Resolvable<T>
get
singleton
Returns the singleton instance currentInstance, or creating it if necessary.
If _constructor itself throws, the throw is absorbed into a
Sync.err(...) so this getter honours the package contract that only
@unsafeOrError members can escape with a thrown exception. The failed
Sync.err is cached just like a successful construction would be —
subsequent reads see the same Err until resetSingleton is called.
If _constructor itself reads singleton (direct or indirect recursion
into the same Lazy), this returns a Sync.err(...) rather than
recursing forever — a stack-overflow is unacceptable in a life-critical
pipeline. The error message names the offending re-entrance so callers
can find the circular dependency.
Implementation
@pragma('vm:prefer-inline')
Resolvable<T> get singleton {
final cached = currentInstance;
if (cached is Some<Resolvable<T>>) return cached.value;
if (_constructing) {
return Sync.err(
Err<T>(
'Lazy<$T>.singleton was accessed re-entrantly from inside its own '
'constructor — circular dependency detected.',
),
);
}
_constructing = true;
Resolvable<T> fresh;
try {
fresh = _constructor();
} on Err catch (err) {
fresh = Sync.err(err.transfErr<T>());
} catch (error, stackTrace) {
fresh = Sync.err(Err<T>(error, stackTrace: stackTrace));
} finally {
_constructing = false;
}
currentInstance = Some(fresh);
return fresh;
}