Einzelnen Beitrag anzeigen

peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
672 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Klassen variabel (z.B. aus Datenbank heraus) registrieren

  Alt 29. Mai 2019, 11:32
Hallo die Gemeinde,

ich habe in einem Projekt eine ganze Latte an Klasse zu registrieren:

registerclass(TFrmxyz...)

Nun meine Frage: kann man dieses über Variablen steuern?

Ich würde die Klassen gern aus einer DB als "Liste" einlesen, weil immer nur die Formulare generiert werden, die für diesen User zugelassen sind.
Am liebsten würde ich mit der Uses-Klausel ähnlich verfahren, aber ich glaube, das ist nicht möglich?

Beste Grüsse

mcinternet
Was Du aus der Datenbank holen kannst sind die Namen der Klassen als String, nicht war? Was Du dann brauchst ist eine Methode, um aus diesem String eine Referenz auf die Klasse (zur Laufzeit) zu erzeugen. Das sollte mit Hilfe von extended RTTI möglich sein.

Delphi-Quellcode:
procedure TForm1.RunTest;
var
  LContext : TRttiContext;
  LType : TRttiType;
begin
  LContext := TRttiContext.Create;
  try
    LType := LContext.FindType(self.QualifiedClassName);
    if LType.IsInstance then
      memo1.lines.Add('Found: '+LType.QualifiedName)
    else
      memo1.lines.Add(Classname + ' not found');
  finally
    LContext.Free;
  end;
end;
Das Problem ist hier, dass FindType einen "qualified name" erwartet, d.h. eine Kombination aus Unit und Klassennamen, separiert durch einen Punkt. Wenn Du also in der Datenbank nur die Klassennamen abgelegt hast wird es etwas aufweniger. Dann mußt Du über TRttiContext.GetTypes die Liste aller bekannten Typen holen (und das sind Tausende!) und Dir die benötigten selbst in der Liste suchen. Nicht gerade flott, aber das machst Du ja nur einmal, beim Start der Anwendung.

Ansonsten gibt es noch die self-made Lösung: Bau deine eigene Klassenliste (basierend auf TClasslist oder TList<TClass>). Das wäre ein Singleton-Object, in das jede Formunit in der Initialisation-Sektion ihre Formklasse registriert. Dann brauchst Du später nur noch in dieser Liste suchen.

Was Du aber nicht vermeiden kannst, ist alle Forms (um die geht es ja wohl hier) auch in die Anwendung einzubinden, egal ob sie später gebraucht werden oder nicht. Rtti wird halt nur für Typen erzeugt, die auch einkompiliert werden, und das gleiche gilt für Unit-Initialisations.

Wenn Du wirklich auch nur ausliefern willst was der Kunde verwenden darf brauchts Du ein anderes Design der Anwendung. In diesem Fall muss die Anwendung auf Packages basieren, wobei kundenspezifische Teile der Anwendung in eigenen Packages untergebracht werden, die dann zur Laufzeit dynamisch geladen werden. Wenn Du bisher kein solches Design verwendet hast und die Anwendung praktisch schon existiert ist die Umarbeitung ein erheblicher Aufwand, und auch die Auslieferung wird komplexer, da Du jede Menge Packages (RTL, VCL, 3rd-party) mit installieren musst. Packages sind all or nothing, und da jede Unit nur in einer der Packages vorkommen darf erfordert die Aufteilung existierenden Kodes eine Menge Planung und Vorarbeit, besonders bei schlampig gebauten RAD-Anwendungen mit vielen wechselseitigen Abhängigkeiten zwischen Units.
Peter Below
  Mit Zitat antworten Zitat