Freigeben über


Überschreiben und Erweitern der generierten Klassen

Ihre DSL-Definition ist eine Plattform, auf der Sie eine leistungsstarke Reihe von Tools erstellen können, die auf einer domänenspezifischen Sprache basieren. Viele Erweiterungen und Anpassungen können vorgenommen werden, indem die klassen überschrieben und erweitert werden, die aus der DSL-Definition generiert werden. Zu diesen Klassen gehören nicht nur die Domänenklassen, die Sie im DSL-Definitionsdiagramm explizit definiert haben, sondern auch andere Klassen, die die Toolbox, Explorer, Serialisierung usw. definieren.

Erweiterbarkeitsmechanismen

Es werden mehrere Mechanismen bereitgestellt, mit denen Sie den generierten Code erweitern können.

Außerkraftsetzen von Methoden in einer partiellen Klasse

Partielle Klassendefinitionen ermöglichen die Definition einer Klasse an mehreren Stellen. Auf diese Weise können Sie den generierten Code vom Code trennen, den Sie selbst schreiben. In Ihrem manuell geschriebenen Code können Sie vom generierten Code geerbte Klassen überschreiben.

Wenn Sie beispielsweise in Ihrer DSL-Definition eine Domänenklasse mit dem Namen Bookdefinieren, können Sie benutzerdefinierten Code schreiben, der Überschreibungsmethoden hinzufügt:

public partial class Book
{
   protected override void OnDeleting()
   {
      MessageBox.Show("Deleting book " + this.Title);
      base.OnDeleting();
   }
}

Hinweis

Um Methoden in einer generierten Klasse außer Kraft zu setzen, schreiben Sie immer Ihren Code in eine Datei, die von den generierten Dateien getrennt ist. In der Regel ist die Datei in einem Ordner mit dem Namen CustomCode enthalten. Wenn Sie Änderungen am generierten Code vornehmen, gehen sie verloren, wenn Sie den Code aus der DSL-Definition neu generieren.

Um zu ermitteln, welche Methoden Sie überschreiben können, geben Sie override in der Klasse ein, gefolgt von einem Leerzeichen. Die IntelliSense-QuickInfo informiert Sie, welche Methoden außer Kraft gesetzt werden können.

Double-Derived-Klassen

Die meisten Methoden in generierten Klassen werden von einem festen Satz von Klassen in den Modellierungsnamespaces geerbt. Einige Methoden werden jedoch im generierten Code definiert. In ordnungsmäßig bedeutet dies, dass Sie sie nicht überschreiben können; Sie können in einer Teilklasse die Methoden, die in einer anderen Teildefinition derselben Klasse definiert sind, nicht außer Kraft setzen.

Trotzdem können Sie diese Methoden überschreiben, indem Sie das Flag "Generates Double Derived" für die Domänenklasse festlegen. Dies bewirkt, dass zwei Klassen generiert werden, eine eine abstrakte Basisklasse des anderen. Alle Methoden- und Eigenschaftsdefinitionen befinden sich in der Basisklasse, und nur der Konstruktor befindet sich in der abgeleiteten Klasse.

Beispielsweise hat die Domänenklasse in der Beispielbibliothek.dsl die Eigenschaft Generates``Double Derived auf true gesetzt. Der generierte Code für diese Domänenklasse enthält zwei Klassen:

  • CirculationBookBase, die eine abstrakte Klasse darstellt und alle Methoden und Eigenschaften umfasst.

  • CirculationBook, das von CirculationBookBase abgeleitet ist. Es ist leer, mit Ausnahme seiner Konstruktoren.

Um eine Methode außer Kraft zu setzen, erstellen Sie eine partielle Klassen-Definition der abgeleiteten Klasse, wie z. B. CirculationBook. Sie können sowohl die generierten Methoden als auch die vom Modellierungsframework geerbten Methoden überschreiben.

Sie können diese Methode mit allen Elementtypen verwenden, einschließlich Modellelemente, Beziehungen, Formen, Diagrammen und Verbindern. Sie können auch Methoden anderer generierter Klassen außer Kraft setzen. Einige generierte Klassen, z. B. ToolboxHelper, werden immer doppelt abgeleitet.

Benutzerdefinierte Konstruktoren

Sie können einen Konstruktor nicht außer Kraft setzen. Auch in zweifach abgeleiteten Klassen muss der Konstruktor in der abgeleiteten Klasse sein.

Wenn Sie Ihren eigenen Konstruktor bereitstellen möchten, können Sie dies tun, indem Sie für die Domänenklasse in der DSL-Definition festlegen Has Custom Constructor . Wenn Sie auf "Alle Vorlagen transformieren" klicken, enthält der generierte Code keinen Konstruktor für diese Klasse. Es enthält einen Aufruf des fehlenden Konstruktors. Dies führt zu einem Fehlerbericht, wenn Sie die Lösung erstellen. Doppelklicken Sie auf den Fehlerbericht, um einen Kommentar im generierten Code anzuzeigen, der erläutert, was Sie bereitstellen sollten.

Schreiben Sie eine partielle Klassendefinition in einer Datei, die von den generierten Dateien getrennt ist, und stellen Sie den Konstruktor bereit.

Gekennzeichnete Erweiterungspunkte

Ein gekennzeichneter Erweiterungspunkt ist eine Stelle in der DSL-Definition, an der Sie eine Eigenschaft oder ein Kontrollkästchen festlegen können, um anzugeben, dass Sie eine benutzerdefinierte Methode bereitstellen. Benutzerdefinierte Konstruktoren sind ein Beispiel. Weitere Beispiele sind das Festlegen einer Domäneneigenschaft auf "Berechneter Speicher" oder "Benutzerdefinierter Speicher" oder das Festlegen des Flags "Is Custom" in einem Verbindungsgenerator.

Ein Buildfehler tritt in jedem Fall auf, wenn Sie das Flag setzen und den Code neu generieren. Doppelklicken Sie auf den Fehler, um einen Kommentar anzuzeigen, der erläutert, was Sie bereitstellen müssen.

Regeln

Mit dem Transaktions-Manager können Sie Regeln definieren, die vor dem Ende einer Transaktion ausgeführt werden, in der ein bestimmtes Ereignis aufgetreten ist, z. B. eine Änderung in einer Eigenschaft. Regeln werden in der Regel verwendet, um die Synchronisierung zwischen verschiedenen Elementen im Speicher aufrechtzuerhalten. Beispielsweise werden Regeln verwendet, um sicherzustellen, dass das Diagramm den aktuellen Status des Modells anzeigt.

Regeln werden pro Klasse definiert, sodass Sie keinen Code haben müssen, der die Regel für jedes Objekt registriert. Weitere Informationen finden Sie unter Regeln, die Änderungen innerhalb des Modells weitergeben.

Shop-Ereignisse

Der Modellierungsspeicher stellt einen Ereignismechanismus bereit, mit dem Sie auf bestimmte Arten von Änderungen im Speicher lauschen können, einschließlich Hinzufügen und Löschen von Elementen, Änderungen an Eigenschaftswerten usw. Die Ereignishandler werden nach dem Schließen der Transaktion aufgerufen, in der die Änderungen vorgenommen wurden. In der Regel werden diese Ereignisse verwendet, um Ressourcen außerhalb des Stores zu aktualisieren.

.NET-Ereignisse

Sie können einige Ereignisse für Shapes abonnieren. Beispielsweise können Sie auf Mausklicks auf ein Shape lauschen. Sie müssen Code schreiben, der das Ereignis für jedes Objekt abonniert. Dieser Code kann in einer Außerkraftsetzung von InitializeInstanceResources() geschrieben werden.

Einige Ereignisse werden in ShapeFields generiert, die zum Zeichnen von Verzierungen auf einer Form verwendet werden. Ein Beispiel finden Sie unter So geht's: Klick auf eine Form oder einen Dekorator abfangen.

Diese Ereignisse treten in der Regel nicht innerhalb einer Transaktion auf. Sie sollten eine Transaktion erstellen, wenn Sie Änderungen am Store vornehmen möchten.