Einzelnen Beitrag anzeigen

Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#1

Tvirtualmethodinterceptor - unproxification

  Alt 16. Nov 2020, 23:42
In einer Factory lasse ich derzeit Klassen als intercepted registrieren und auch erstellen(ähnlich wie beim Standard-Framework SPRING):
Delphi-Quellcode:
type ixx=interface
procedure blub;
end;
tx=class(..,ixx)
procedure blub;virtual;
end;
procedure test;
var x:Ixx;
begin
Tfactory.Reg<Txx>('txx').defaultfor<ixx>.Interceptedby(Txxintercept).Interceptedby(Txx2intercept); //auch multiple interceptions sind derzeit möglich. Im Allgemeinen wird das hier durch den Gebrauch von Attributen abgekürzt, soll aber der darstellung dienen.
//interceptedby sucht die entsprechende Klasse raus, erstellt ein Interceptor-Objekt (vmi.proxify(obj)) und hinterlegt dieses in einer der 'txx'-Registrierung zugehörigen liste.
//get object
  X := Tfactory.New<ixx>;
//do something
  X.Blub;
x:=nil;

end;
Soweit so gut.
Nur, wenn ich jetzt allerdings nicht per unreg<> die klasse und alle zugehörigen Interceptor-objekte lösche:
Delphi-Quellcode:
 Var
  Reg := Tfactory.Registrations['txx'];
  Var
  I := High(Reg.Interceptors);
  While I >= 0 Do
  Begin
    Var
    Proxy := Reg.Interceptors[I];
    If Assigned(Proxy)
    Then
    Begin
      Proxy.Unproxify(X);//vmi.unproxify...
      Proxy := Nil;
    End;
    Dec(I);
  End;
tfactory.unreg<txx>;
, bekomme ich natürlich Speicherlöcher.

Folgendes drängt sich dann auf:
Die Factory / der Container weiss (bisher) nicht um jedes von ihr erstelltes Objekt (zzt nur um die Singletons).
Wie wäre denn denkbar, dass sich ein/ mehrere interceptor beim aufruf von Txx.destroy selber mitfreigibt bzw die Interception auflöst, was ja genügt, wenn die Freigabe bei unreg<> passiert? krieg ich das irgendwie an Tobject attached? oder muss ich auf die Standard-Freigabe mit destroy / nil verzichten und ALLE Instanzen auch im Container registrieren?

Folgender interceptor scheint auf den ersten Blick zu funktionieren, allerdings nur, wenn alle abgeleiteten Klassen mit destructor (zb
Delphi-Quellcode:
{...}
  Tfactory.Reg<Tobjectinterceptor>('basicinterceptor');
{...}
 [Interceptor('basicinterceptor')]
ty=class(tx)
 destructor destroy;override;
end;
ebenfalls annotiert / intercepted werden. Das erscheint mir seltsam.
Delphi-Quellcode:
Constructor Tobjectinterceptor.Create(Aclass: Tclass);
Begin
  Inherited;
  Onbefore :=
      Procedure(Instance: TObject; Method: TRttiMethod;
    Const Args: TArray<TValue>; Out DoInvoke: Boolean; Out Result: TValue)
    Begin
      Doinvoke := True;
      If Lowercase(Method.Name) = 'freeinstance'
      Then
        If Assigned(Vmi)
        Then
          Try
            Vmi.OnBefore := Nil;
            Vmi.OnAfter := NiL;
            Vmi.OnException := Nil;
            Vmi.Unproxify(Target);
          Finally
          End;
    End;
End;

Geändert von Sequitar (17. Nov 2020 um 01:39 Uhr)
  Mit Zitat antworten Zitat