Snippets

Stefan Glienke Scopes and DI

Created by Stefan Glienke
unit Unit1;

interface

uses
  SysUtils,
  Spring.Container;

type
  IScoped<T> = interface
    ['{4DFFFC15-E7A5-4BB8-8429-FC5B9FB10623}']
    function Get: T;
    procedure Reset;
  end;

  TScoped<T> = class(TInterfacedObject, IScoped<T>)
  private
    fFactory: TFunc<T>;
    fInstance: T;
  public
    constructor Create(const factory: TFunc<T>);

    function Get: T;
    procedure Reset;
  end;

  IFoo = interface
    ['{D46034DD-7F66-4F04-BA8F-57C403ADB56D}']
  end;

  TFoo = class(TInterfacedObject, IFoo)
  end;

procedure Main(const container: TContainer);

implementation

{ TScoped<T> }

constructor TScoped<T>.Create(const factory: TFunc<T>);
begin
  inherited Create;
  fFactory := factory;
end;

function TScoped<T>.Get: T;
begin
  // assume we are only handling reference types here
  if not Assigned(PPointer(@fInstance)^) then
    fInstance := fFactory;
  Result := fInstance;
end;

procedure TScoped<T>.Reset;
begin
  fInstance := Default(T);
end;

procedure Main(const container: TContainer);
var
  f1, f2: IFoo;
  s: IScoped<IFoo>;
begin
  container.RegisterType<IFoo,TFoo>;
  container.RegisterType<IScoped<IFoo>,TScoped<IFoo>>.AsSingleton;
  container.Build;
  s := container.Resolve<IScoped<IFoo>>;
  f1 := s.Get;
  f2 := s.Get;
  Assert(f1 = f2);
  s.Reset;
  f2 := s.Get;
  Assert(f1 <> f2);
end;

end.

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.