Skip to main content

Interface Binding

Interface binding maps a Delphi IInterface-derived type to a concrete class. The container resolves the binding by GUID, so the caller only depends on the interface, never the implementation.

Method signature​

procedure SingletonInterface<I: IInterface; T: class, constructor>(
const ATag: string = '';
const AOnCreate: TProc<T> = nil;
const AOnDestroy: TProc<T> = nil;
const AOnConstructorParams: TConstructorCallback = nil);

Declared in unit Inject, class TInject.

Prerequisites​

Your interface must have a GUID attribute:

type
IMyService = interface
['{12345678-ABCD-EF01-2345-6789ABCDEF01}']
procedure DoWork;
end;

The GUID is used as the registry key internally (GUIDToString).

Basic registration and resolution​

uses
Inject, MyServices;

// Registration (typically in unit initialization)
GetInjector.SingletonInterface<IMyService, TMyServiceImpl>;

// Resolution (in any consumer)
var LSvc: IMyService;
LSvc := GetInjector.GetInterface<IMyService>;
LSvc.DoWork;

Resolution method​

function GetInterface<I: IInterface>(const ATag: string = ''): I;
  • Looks up the GUID of I in FRepositoryInterface.
  • If found and not yet instantiated, creates via RTTI and caches the TValue.
  • Raises EServiceNotFound if the interface is not registered.

Using ATag for multiple registrations​

If you need multiple implementations of the same interface (e.g., different strategies), use the ATag parameter to distinguish them:

GetInjector.SingletonInterface<IPaymentGateway, TStripeGateway>('stripe');
GetInjector.SingletonInterface<IPaymentGateway, TPayPalGateway>('paypal');

var LStripe := GetInjector.GetInterface<IPaymentGateway>('stripe');
var LPayPal := GetInjector.GetInterface<IPaymentGateway>('paypal');

Real example from the DependencyInjection_Interface sample​

// In unit initialization — wires the DFe engine to a concrete ACBr provider
initialization
GetInjector.SingletonInterface<IDFeEngine, TDFeEngineACBr>;

// In a controller constructor — consumer only knows IDFeEngine
constructor TGlobalController.Create;
begin
inherited;
FDFeEngine := GetInjector.GetInterface<IDFeEngine>;
end;

Error handling​

ConditionException raised
Interface already registered with same GUID/tagEServiceAlreadyRegistered
Interface not registered at resolution timeEServiceNotFound