I want to create a connection provider which issues Shared<T> and holds on to a Weak<T> but even though only 1 T instance gets created there are 2 attempts to destroy.
I have included a basic example below.
TMyObj = class
private
class var
fNextId: Integer;
var
fId: Integer;
public
constructor Create;
destructor Destroy; override;
end;
IProv = interface
['{0497DFE9-A77C-4250-82AF-FDA3823A91EC}']
function Get: Shared<TMyObj>;
function GetNew: Shared<TMyObj>;
end;
TProv = class(TInterfacedObject, IProv)
private
fInstance: Weak<TMyObj>;
protected
function Get: Shared<TMyObj>;
function GetNew: Shared<TMyObj>;
end;
THolder = class
private
fO: Shared<TMyObj>;
public
constructor Create(O: Shared<TMyObj>);
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
var P:=TProv.Create as IProv;
var H:=THolder.Create(P.Get);
var H2:=THolder.Create(P.Get);
FreeAndNil(H);
FreeAndNil(H2);
OutputDebugString('End');
end;
{ TMyObj }
constructor TMyObj.Create;
begin
fId:=InterlockedIncrement(fNextId);
OutputDebugString(PChar(fId.ToString+' Creating On '+GetCurrentThreadId.ToString));
end;
destructor TMyObj.Destroy;
begin
OutputDebugString(PChar(fId.ToString+' Destroying On '+GetCurrentThreadId.ToString));
inherited;
end;
{ TProv }
function TProv.Get: Shared<TMyObj>;
begin
if fInstance.IsAlive then
Exit(fInstance.Target);
Result:=GetNew;
fInstance:=Result;
end;
function TProv.GetNew: Shared<TMyObj>;
begin
Result:=TMyObj.Create;
end;
{ THolder }
constructor THolder.Create(O: Shared<TMyObj>);
begin
fO:=O;
end;
I then thought that Weak<T> would only work for interfaces so changed the implementation to hold a Weak<IShared<T>> but then false is returned when I call Weak.IsAlive.