Udostępnij za pośrednictwem


Zastępowanie i rozszerzanie wygenerowanych klas

Definicja DSL to platforma, na której można utworzyć zaawansowany zestaw narzędzi opartych na języku specyficznym dla domeny. Wiele rozszerzeń i adaptacji można wykonać przez zastąpienie i rozszerzenie klas generowanych na podstawie definicji DSL. Te klasy obejmują nie tylko klasy domeny, które zostały jawnie zdefiniowane na diagramie definicji DSL, ale także inne klasy definiujące przybornik, eksplorator, serializacji itd.

Mechanizmy rozszerzalności

Dostępnych jest kilka mechanizmów umożliwiających rozszerzenie wygenerowanego kodu.

Zastępowanie metod w klasie częściowej

Częściowe definicje klas umożliwiają definiowanie klasy w więcej niż jednym miejscu. Dzięki temu można oddzielić wygenerowany kod od kodu, który samodzielnie piszesz. W kodzie napisanym ręcznie można zastąpić klasy dziedziczone przez wygenerowany kod.

Jeśli na przykład w definicji DSL zdefiniujesz klasę domeny o nazwie Book, możesz napisać kod niestandardowy, który dodaje metody zastąpienia:

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

Uwaga

Aby zastąpić metody w wygenerowanej klasie, zawsze napisz kod w pliku oddzielonym od wygenerowanych plików. Zazwyczaj plik znajduje się w folderze o nazwie CustomCode. Jeśli wprowadzisz zmiany w wygenerowany kod, zostaną one utracone po wygenerowaniu kodu z definicji DSL.

Aby dowiedzieć się, jakie metody można zastąpić, wpisz przesłonięcia w klasie, a następnie spację. Etykietka narzędzia IntelliSense informuje o tym, jakie metody można zastąpić.

Klasy pochodne dwupowodowe

Większość metod w wygenerowanych klasach jest dziedziczona z stałego zestawu klas w przestrzeniach nazw modelowania. Jednak niektóre metody są zdefiniowane w wygenerowany kod. Zazwyczaj oznacza to, że nie można ich zastąpić; w jednej klasie częściowej nie można zastąpić metod zdefiniowanych w innej częściowej definicji tej samej klasy.

Można jednak zastąpić te metody, ustawiając flagę Generates Double Derived dla klasy domeny. Powoduje to wygenerowanie dwóch klas, z których jedna jest abstrakcyjną klasą bazową drugiej. Wszystkie definicje metody i właściwości znajdują się w klasie bazowej, a tylko konstruktor znajduje się w klasie pochodnej.

Na przykład w przykładowej bibliotece.dsl CirculationBook klasa domeny ma właściwość ustawioną Generates``Double Derived na true. Wygenerowany kod dla tej klasy domeny zawiera dwie klasy:

  • CirculationBookBase, który jest abstrakcyjny i który zawiera wszystkie metody i właściwości.

  • CirculationBook, który pochodzi z .CirculationBookBase Jest on pusty, z wyjątkiem jego konstruktorów.

Aby zastąpić dowolną metodę, należy utworzyć częściową definicję klasy pochodnej, taką jak CirculationBook. Można zastąpić zarówno wygenerowane metody, jak i metody dziedziczone ze struktury modelowania.

Tej metody można używać ze wszystkimi typami elementów, w tym elementami modelu, relacjami, kształtami, diagramami i łącznikami. Można również zastąpić metody innych wygenerowanych klas. Niektóre wygenerowane klasy, takie jak ToolboxHelper, są zawsze pochodne podwójnie.

Konstruktory niestandardowe

Nie można zastąpić konstruktora. Nawet w klasach dwupowodowych konstruktor musi znajdować się w klasie pochodnej.

Jeśli chcesz podać własny konstruktor, możesz to zrobić, ustawiając Has Custom Constructor dla klasy domeny w definicji DSL. Po kliknięciu przycisku Przekształć wszystkie szablony wygenerowany kod nie będzie zawierać konstruktora dla tej klasy. Będzie zawierać wywołanie brakującego konstruktora. Spowoduje to wyświetlenie raportu o błędach podczas tworzenia rozwiązania. Kliknij dwukrotnie raport o błędach, aby wyświetlić komentarz w wygenerowanym kodzie, który wyjaśnia, co należy podać.

Napisz definicję klasy częściowej w pliku, który jest oddzielony od wygenerowanych plików i podaj konstruktor.

Oflagowane punkty rozszerzenia

Punkt rozszerzenia oflagowany to miejsce w definicji DSL, w którym można ustawić właściwość lub pole wyboru, aby wskazać, że zostanie wyświetlona metoda niestandardowa. Konstruktory niestandardowe są jednym z przykładów. Inne przykłady obejmują ustawienie Kind właściwości domeny na wartość Calculated lub Custom Storage lub ustawienie flagi Is Custom w konstruktorze połączenia.

W każdym przypadku po ustawieniu flagi i wygenerowaniu kodu zostanie wyświetlony błąd kompilacji. Kliknij dwukrotnie błąd, aby wyświetlić komentarz wyjaśniający, co należy podać.

Reguły

Menedżer transakcji umożliwia definiowanie reguł uruchamianych przed końcem transakcji, w której wystąpiło wyznaczone zdarzenie, takie jak zmiana właściwości. Reguły są zwykle używane do utrzymania synchronizacji między różnymi elementami w magazynie. Na przykład reguły służą do upewnienia się, że na diagramie jest wyświetlany bieżący stan modelu.

Reguły są definiowane dla poszczególnych klas, dzięki czemu nie trzeba mieć kodu, który rejestruje regułę dla każdego obiektu. Aby uzyskać więcej informacji, zobacz Reguły propagacji zmian w modelu.

Przechowywanie zdarzeń

Magazyn modelowania udostępnia mechanizm zdarzeń, którego można użyć do nasłuchiwania określonych typów zmian w magazynie, w tym dodawania i usuwania elementów, zmian wartości właściwości itd. Programy obsługi zdarzeń są wywoływane po zamknięciu transakcji, w której wprowadzono zmiany. Zazwyczaj te zdarzenia są używane do aktualizowania zasobów poza magazynem.

Zdarzenia platformy .NET

Możesz subskrybować niektóre zdarzenia na kształtach. Na przykład możesz nasłuchiwać kliknięć myszą na kształcie. Musisz napisać kod, który subskrybuje zdarzenie dla każdego obiektu. Ten kod można napisać w przesłonięciu InitializeInstanceResources().

Niektóre zdarzenia są generowane na polach ShapeFields, które są używane do rysowania dekoratorów na kształcie. Przykład można znaleźć w temacie How to: Intercept a Click on a Shape or Decorator (Jak przechwytywać kliknięcie kształtu lub dekoratora).

Te zdarzenia zwykle nie występują wewnątrz transakcji. Jeśli chcesz wprowadzić zmiany w sklepie, należy utworzyć transakcję.