Onion Model

Länder von Schleupen.CS besitzen eine Onion-Architektur, das die Konzepte von DDD integriert. Hierbei wird der DDD-Layer in eine Ports & Adapter-Architektur eingebunden. Im Zentrum hierbei ist das Domänenmodell, das technikneutral als "reine" POCOs (= plain old csharp objects = simple C#-Klassen mit Daten und Operationen) implementiert wird. Jede weitere äußere Schale greift dabei nur auf die inneren Schalen zu, nicht aber umgekehrt. Der Applicaton Core beinhaltet die Usecase Controller (oder auch Application Services genannt), die als Orchestrator zwischen den anderen Bausteinen fungieren. Dort wo notwendig, werden zusätzliche Domain Service innerhalb des Domain-Layers definiert (etwas ungenau und nicht eingezeichnet am "Rand" des Domänenmodells). Domain Services bilden Domänenlogik ab und nutzen lediglich Aggregate und bilden "übergreifende", reine Domänenlogik ab. Domain Events werden in der Domänen ausgelöst und Handler dieser Ereignisse auf Ebene der UseCase Controller implementiert um Seiteneffekte zu implementieren.

Anmerkung: Im Gegensatz zu Domain Services sind Usecase Controller Vermittler, um die Schalen miteinander zu verknüpfen.

Onion Model von Schleupen.CS 3.0 in der Mikroarchitektur

Der Application Core wird also möglichst technologieneutral implementiert und die technologischen Abhängigkeiten sind weiter außen im Schalenmodell zu finden. Damit ist es einfach möglich, Technik auszutauschen!

Diese Darstellung ist unsere Sicht und unser Vokabular auf viele artverwandte Darstellungen (Onion Model, Clean Architecture, Hexagonales Modell, etc.), das folgende Ziele hat:

  • Isolierung fachlicher von technischer Logik.
  • Platzierung der Domäne im Zentrum der Entwicklung als isoliertes Objekt-Modell.
  • Äußere Schichten greifen innere zu. Hier ist ggf. Dependency Inversion notwendig.
  • Der Code des Application Core code kann kompiliert und in einer anderen Infratstruktur ausgeführt werden-
  • Die Konzepte von DDD werden berücksichtigt.

Dependency Inversion

Um der Regel des Zugriffs von außen nach innen gerecht zu werden, wird Dependency Inversion als eines der SOLID-Prinzipien angewendet. Dabei sollen High-Level-Klassen nicht von Low-Level-Klassen abhängig sein, sondern beide von Abstraktionen (z.B. Interfaces) um diese Richtungsabhängigkeit zu steuern.

Dabei sollen Interfaces nicht von Details abhängig sein, sondern Details von Interfaces. Um das zu erläutern, zeigt folgende Abbildung ausgehend von einer Schichtenarchitektur den Übergang zum Onion Model. Dabei besteht der eigentliche Trick darin, die Schnittstellen zu verschieben, wodurch sich die Abhängigkeitsbeziehung dreht. Dies zeigt die nachfolgende Abbildung.

Dependency Inversion

Damit gelingt es schlussendlich, den Application Core unabhängig von Technik zu halten. Dies ist sehr sinnvoll, damit technologische Änderungen wie beispielsweise die Ablösung der Kommunikationstechnologie von WCF zu Web-APIs möglichst einfach durchzuführen sind.

Aber auch die Möglichkeit des Testens durch Unittests ist einfacher isoliert möglich. Hierzu benötigt man nur die innere Schale und die Abhängigkeiten in Form von Schnittstellen können einfach durch Verwendung von Test-Doublen (Mocks, Stubs, Spys etc.) implementiert werden. Die Isolation entsteht, wenn Klassen keine Abhängigkeiten von Implementierungen mehr enthalten – weder zur Laufzeit, noch zur Übersetzungszeit. Konkrete Abhängigkeiten werden so spät wie möglich aufgelöst, d.h. zur Laufzeit.

Projektstruktur

Die Abbildung des Onion Models auf die Projektstruktur ist intuitiv und der folgenden Abbildung zu entnehmen.

Onion Model und Default-Projekt-Struktur eines Schleupen.CS 3.0 Landes
Chatbot not allowed
Cookie Consent mit Real Cookie Banner