Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Registrieren von Klassen (https://www.delphipraxis.net/33642-registrieren-von-klassen.html)

barnti 10. Nov 2004 15:08


Registrieren von Klassen
 
Hallo,
ich erzeuge in meiner Anwendung eine Klasse 'PDInterface'. In dieser möchte ich alle für meine Anwendung benötigten Klassen registrieren.
Ist das möglich?
Delphi-Quellcode:
unit PDInterface;
...

constructor TPDInterface.Create(Owner: TComponent); // Owner ist die Anwendung
var
  I: Integer;
  aClass: TPersistentClass;
  ClassName: String;
begin
  FApplication:= Owner;
  FDatabase:= TmyDatabase.Create(Owner);

  For i:=0 to Length(FClassArray) -1 do begin
    // Erzeugt Einträge aus den TabellenNamen der DB
    FClassArray[TClassIndex(i)]:= Database.FTableArray[i];
    // Ermittelt den aktuellen Tabellennamen und stellt ein'TPD' voran, welches dann den Namen
    // der Klasse ergibt
    ClassName:= 'TPD'+FClassArray[TClassIndex(i)];
    // Casten auf persistente zu registrierende Klasse
    aClass:= TPersistentClass(ClassName);
   // Versuch die aktuelle Klasse zu registrieren
   RegisterClass(aClass);
  end // for
end;
Leider schlägt das Registrieren mit eine Schutzverletzung fehl.

Kann jemand helfen?

mirage228 10. Nov 2004 15:28

Re: Registrieren von Klassen
 
Hi,

ist Deine Klasse von TPersistent abgeleitet bzw. ist die RTTI ({$M+}) dafür aktiviert?

mfG
mirage228

barnti 10. Nov 2004 15:32

Re: Registrieren von Klassen
 
Hi,

ja die zu registrierenden Klassen sind alle vom Typ TPersistent bzw. Unterklassen:

Delphi-Quellcode:
TPersistent
    |
TPDObject
    |
TPDMeineZuRegistrierendeKlasse

mirage228 10. Nov 2004 15:34

Re: Registrieren von Klassen
 
Hi,

dann versuch mal die Klasse im initialization Abschnitt der Unit zu registrieren.

mfG
mirage228

barnti 10. Nov 2004 15:36

Re: Registrieren von Klassen
 
Hi,

das war meine Frage: Kann ich das NUR dort?
Denn es müssen vorher erst einige Klassen zur Verfügung stehen, die die zu registrierenden Klassen ermitteln...!?

mirage228 10. Nov 2004 15:42

Re: Registrieren von Klassen
 
Zitat:

Zitat von barnti
Hi,

das war meine Frage: Kann ich das NUR dort?
Denn es müssen vorher erst einige Klassen zur Verfügung stehen, die die zu registrierenden Klassen ermitteln...!?

Hi,

Achso, das weiss ich nicht. Jedoch wurden bei den Programmen, die ich gesehen habe, die Klassen im initialization Abschnitt initialisiert.

Noch 2 Fragen:
ist aClass eventuell = nil ?
Hast Du schon versucht mit Debug DCUs zu kompilieren und auch in Delphi Sourcen mit reingetraced?

mfG
mirage228

maximov 10. Nov 2004 15:55

Re: Registrieren von Klassen
 
Delphi-Quellcode:
var...
  ClassName: String;
...
  aClass:= TPersistentClass(ClassName);
:shock: Du kannst nicht einfach einen String auf eine metaklasse casten :wink: ..abgesehen davon solltest du diese variable nicht ClassName nennen, da dies eine klassen-methode von TObject ist.

Du brauchst hier schon explizit die klasse. das was du da versuchst, geht auf keinen fall...und wenn es gehen würde, dann bräuchtest du die klasse ja nicht mehr registrieren.

Aber erzähl doch mal was du erreichen willst?

barnti 10. Nov 2004 18:57

Re: Registrieren von Klassen
 
Hallo,

ich möchte in die für meine Anwendung benötigten Klassen automatisch generieren. Dazu existiert für jede DB-Tabelle eine eigene Klasse. Bei der Initialisierung der Anwendung oder beim Erzeugen des Hauptformulars möchte ich die benötigten Klassen erzeugen. Möglichst über eine einzige Prozedur, die über ein Array der Tabellennamen iteriert.

Ich bin zur Zeit nicht an meinem Arbeitsplatz, so dass ich erst morgen wieder genauer auf das Problem eingehen kann...

barnti 11. Nov 2004 07:41

Re: Registrieren von Klassen
 
Hallo,

nun noch einaml zurück zum Thema. Ich möchte in einer Klasse alle für die Konfiguration erforderlichen Daten ablegen. Dazu gehören auch Prozeduren und Funktionen, die mir zur Laufzeit Konfigurationsarameter ermitteln. Hier mal etwas Code:
Delphi-Quellcode:
unit ConfigFile;

interface

uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls,
  Forms, Dialogs;

type
  TConfigFile = class (TObject)

...

TPDObjectClass = class of TPersistent;

{ Hier müssen alle in der Datenbank enthaltenen Tabellen angegeben werden.
}
TClassIndex = (   
              {1}    Ansprechpartner,
              {2}    Auftrag,
              {3}    auftragstatus,
              {4}    ...
              {5}
              {6}   
              {7}   
              {8}   
              {9}   
              {10}   
              {11}   
              {12}   
              {13}   
              {14}   
              {15}   
              {16}   
              {17}   
              {18}   
              {19}   
              {20}   
              {21}   
              {22}   
              {23}   
              {24}   
              {25}   
              {26}   
              {27}   );

// Beinhaltet die Namen der Tabellen. Um mit einer Klasse zu Arbeiten, wird die
// entsprechende Klasse aus dem Array per Tabellenname oder per Index gesucht und ein 'TPD'
// vorangestellt, um den Namen der Klasse zu erhalten
TClassArray= array[Ansprechpartner..zustaendigkeit] of String;

procedure Register;

implementation
// Hier stehen statische Parameter
const
  C_DatabaseName = 'Name';
  C_Host        = 'Host';
...

//Das 'ClassArray' lade ich zur Laufzeit aus der DB (TableList):
 for i:=0 to TableList.Count-1 do
      ClassArray[TClassIndex(i)]:= List.Strings[i];

...

//Nun kann ich folgendes machen:
function TPDInterface.GetPDObject(Index: Integer): TPDObject;
var
  pdClass: TPDObjectClass;
begin
  pdClass:= findClass('TPD'+ClassArray[TClassIndex(index)]);
  //pdClass:= findClass('TPDAnsprechpartner');
  if FPDObjects[index]= NIL then FPDObjects[index]:= TPDObject.Create(Database);
  result:= FPDObjects[index];
Dazu müssen die Klassen allerdings registriert sein:
Delphi-Quellcode:
initialization
 RegisterClasses([TPDAnsprechpartner,TPDAuftrag, TPDAuftragstatus,...]);
Da ich aber erst zur Laufzeit auf die Config-Klasse zugreifen kann, muss ich das Registrieren also an einer anderen Stelle tun als im Initialization-Teil.

Ich dachte also das könnte ich auch beim Erzeugen meines Hauptformulars tun:
Delphi-Quellcode:
unit main
...
constructor TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  aClass: TPDObjectClass;
  ClassName: String;
begin
  FApplication:= Owner;
  // Hier werden alle Parameter des ConfigFiles geladen und die TabellenNamen der DB ermittelt
  FDatabase:= TmyDatabase.Create(Owner);

  For i:=0 to Length(FClassArray) -1 do begin
    FClassArray[TClassIndex(i)]:= Database.FTableArray[i];
    ClassName:= 'TPD'+FClassArray[TClassIndex(i)];
    aClass:= TPDObjectClass(ClassName);
    RegisterClass(aClass);
  end // for
end;
Mein Hauptanliegen ist es alle Konfigurationsparameter in einer eigenen Klasse zu halten (ConfigFile).
Kann jemand dazu Stellung nehmen? Kann jemand helfen?

choose 11. Nov 2004 08:55

Re: Registrieren von Klassen
 
Hallo barnti,

klingt nach einem interessanten Vorhaben, dass ich in Delphi (außerhalb der VCL) in veröffentlichten Projekten mit Quelltext bisher nur bei Bei Google suchenLog4D sehen konnte.
Generell habe ich zur Lösung ähnlicher Probleme häufig diesen Ansatz gesehen:
  1. Registratur aller Klassen im Initialization-Abschnitt der jeweiligen Unit. Es ist nicht erforderlich, das in einer zentralen Unit zu tun, sondern jede Unit kann die zu registrierenden Klassen in ihrer Implementierungsunit registrieren.
  2. Laden der Konfiguration (dem Mapping), die im Wesentlichen einen Schlüssel (hier: Dein Tabellenname) auf eine Klasse abbildet (hier: ein Klassenname). Ist sie geladen, sind Ausdrücke der Art denkbar
    Delphi-Quellcode:
    myClassName := Configuration.GetClassNameFromKey(myTableName);
    Dieser Schritt könnte zB in Deinem Hauptformular geschehen und es spricht nichts dageben, unterschiedliche Konfigurationen für unterschiedliche Formualare, Abläufe oä vorzuhalten.
  3. Erzeugung der Benötigten Klasse mithilfe der Registratur in der Art
    Delphi-Quellcode:
    with Registration do
      myClass := GetClassFromName(Configuration.GetClassNameFromKey(myTableName);
    myObject := myClass.Create(myContext);

Vielleicht solltest Du Dir noch einmal das Bei Google suchenEntwurfsmuster abstrakte Fabrik (Bei Google suchenabstract factory pattern) ansehen, und in Erwägung ziehen, eine Menge von Fabriken zu konfigurieren, was den Ansatz wesentlich flexibler macht...


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:14 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz