![]() |
Tvirtualmethodinterceptor - unproxification
In einer Factory lasse ich derzeit Klassen als intercepted registrieren und auch erstellen(ähnlich wie beim Standard-Framework SPRING):
Delphi-Quellcode:
Soweit so gut.
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; Nur, wenn ich jetzt allerdings nicht per unreg<> die klasse und alle zugehörigen Interceptor-objekte lösche:
Delphi-Quellcode:
, bekomme ich natürlich Speicherlöcher.
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>; 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
Delphi-Quellcode:
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?
Txx.destroy
Folgender interceptor scheint auf den ersten Blick zu funktionieren, allerdings nur, wenn alle abgeleiteten Klassen mit destructor (zb
Delphi-Quellcode:
ebenfalls annotiert / intercepted werden. Das erscheint mir seltsam.
{...}
Tfactory.Reg<Tobjectinterceptor>('basicinterceptor'); {...} [Interceptor('basicinterceptor')] ty=class(tx) destructor destroy;override; end;
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; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz