Skip to main content

Lazy Load (SingletonLazy)

SingletonLazy combines the shared-instance guarantee of a Singleton with deferred construction: the object is not created until the first time it is requested.

Method signature

procedure SingletonLazy<T: class>(
const AOnCreate: TProc<T> = nil;
const AOnDestroy: TProc<T> = nil;
const AOnConstructorParams: TConstructorCallback = nil);

Declared in unit Inject, class TInject.

note

SingletonLazy accepts T: class only (no constructor constraint). The actual construction is deferred and driven by RTTI inside GetTry<T>.

Basic usage

uses
Inject;

// Register — nothing is constructed yet
GetInjector.SingletonLazy<TExpensiveService>;

// First Get<T> → constructs and caches the instance
var LSvc := GetInjector.Get<TExpensiveService>;

// Subsequent calls → same cached instance
var LSvc2 := GetInjector.Get<TExpensiveService>;
// LSvc = LSvc2

Difference from Singleton

AspectSingletonSingletonLazy
Instance created atRegistration timeFirst resolution
Good forServices always needed at startupServices that may never be needed
Constructor accessImmediateVia RTTI at first Get<T> call

With callbacks

GetInjector.SingletonLazy<TReportGenerator>(
procedure(const AGen: TReportGenerator)
begin
AGen.OutputPath := 'C:\Reports';
end,
procedure(const AGen: TReportGenerator)
begin
AGen.Flush;
end
);

Interaction with events

Inside GetTry<T>, the container calls _ResolverParams to auto-wire constructor parameters from the container when no TConstructorCallback is provided. This means that if TExpensiveService requires other registered services in its constructor, they are resolved automatically at lazy-instantiation time.