Hallo zusammen,
in unserem Projekt, müssen wir dafür sorgen, dass alle verfügbare Klassen des Projektes in den RegisterClasses registriert werden.
Nun habe ich mich ein wenig mit
RTTI und dessen Funktion GetTypes auseinander gesetzt.
Leider erzielen wir bisher nur Teilziele.
Im Projekt Quelltext, stehen rund 400 Klassen, welche beim Starten auch tatsächlich vor den Ausführen der nachfolgenden Funktion initialisiert werden, während die Funktion leider nur 146 relevante davon findet und registriert. Die Filterung nach "TFRM" liegt daran, dass wir explizit alle unsere Klassen die Relevant sind so vorab benennen.
Nun das bestehende Problem der aktuellen Funktion:
Klasse_A wird mittels der Funktion gefunden und wird in RegisterClasses registriert.
Klasse_B wird nicht gefunden.
Beide Klassen erben von Klasse_C, welche gefunden wird und verwenden die selben Uses.
Um zu schauen, ob die fehlende Klasse_B überhaupt irgendwo aufgelistet wird ggf. mit dem
Unit-Namen o.ä., habe ich mit alle Typen "KlassenALL" und alle Klassen "klassen" als Liste ausgeben lassen. Leider findet man in keiner der beiden die entschiedene fehlende Klasse_B.
Habt Ihr eventuell Iden, Gedankenansätze, wieso das so sein könnte oder wo man nochmal nachschauen kann ?
Weiterer Hinweis:
wir wollen das manuelle Registrieren unter dem Block initialization vermeiden, da sonst ebenfalls die Implementierung der Units in den uses erfolgen muss. Durch die hohe Anzahl ist es serh mühselig und der Wartungsaufwand, sowie die Sicherstellung ist zu hoch. In dem Code-Beispiel, habe ich die Uses und initialization mal nur auf ein Beispiel herunter gebrochen.
Verwendete Delphi-Version XE10 Seattle Architect
Bei Fragen einfach melden, vielen Dank vorab
Lg Tobi
Delphi-Quellcode:
uses System.Classes, System.Rtti, System.SysUtils;
procedure FindeAlleKlassen();
implementation
uses fKlasseA
procedure FindeAlleKlassen;
var
ctx: TRttiContext;
typ: TRttiType;
list: TArray<TRttiType>;
i: Integer;
KlassenAll: TStringList;
Klassen: TstringList;
begin
// sucht die Klasse und gibt diese für das Array der RegisterClasses zurück.
ctx := TRttiContext.Create;
list := ctx.GetTypes;
Klassen := TStringList.Create;
Klassen.Clear;
KlassenAll := TStringList.Create;
KlassenAll.Clear;
i := 0;
for typ in list do
begin
//Zum Testen aller typen ohne Instanziierung
KlassenALL.Add(typ.Name);
if typ.IsInstance and not(typ = nil) then
begin
if Pos('TFRM',UpperCase(typ.ToString),1)>0 then
begin
//Zum testen in StringList schrieben und Inhalte nachlesen
Klassen.Add(typ.AsInstance.MetaclassType.ClassName);
//Füge die Klasse den RegisterClasses hinzu.
RegisterClasses([TPersistentClass(typ.AsInstance.MetaclassType)]);
//Zähler i
Inc(i);
end;
end;
end;
// Testzwecke
Klassen.SaveToFile('X:\Klassen.txt');
KlassenALL.SaveToFile('X:\KlassenALL.txt');
ctx.Free;
end;
initialization
RegisterClasses([TfrmKlasseA])