Was ist .NET Aspire?
.Net Aspire ist ein cloud-native application stack , der darauf ausgelegt ist, die Entwicklung von verteilten Systemen in .NET zu vereinfachen.
Ein Cloud-native application stack ist ein Verbund aus kleinen, unanhängigen Modulen, die speziell für die Cloud entwickelt wurden. Diese Module kann man als kleine Programme verstehen, die für sich isoliert laufen und von anderen Programmen angesprochen werden können, ohne dass sie von anderen Programmen abhängig sind.
Anders gesagt kann mit .NET Aspire entwickelt werden, als würde man mit einem Monolithen arbeiten, der in Wahrheit aber aus voneinander entkoppelten und unabhängigen Teilen besteht. Ein Monolith ist, anders als der oben erwähnte Cloud-native application stack, kein Verbund aus mehreren kleinen Programmen, sondern stellen ein oft grösseres Programm dar. Anstatt dass die Module unabhängig voneinander als separate Programme laufen, sind alle Module fester Bestandteil eines monolithischen Programms und direkt voneinander abhängig.
Anstatt manuell Container, bzw. die Module einzeln, hochfahren zu müssen die man eben braucht, um eine Applikation zu entwickeln oder zu erweitern, kümmert sich ein AppHost-Projekt um das Hochfahren von eigenen .Net Projekten, externen Containern, und Konfigurationen. Stellen Sie sich den AppHost wie eine magische Universalfernbedienung vor: Mit nur einem Knopfdruck starten Sie alle Ihre Geräte gleichzeitig. Das Besondere ist aber, dass die Fernbedienung im Hintergrund sofort dafür sorgt, dass jedes Gerät weiss, wie es mit den anderen kommunizieren muss – egal, ob es ein neues Eigenbau-Gerät oder ein gekauftes Markenprodukt ist.
Am Beispiel von Visual Studio benötige ich dank der AppHost-Konfiguration nur den Debug-Knopf (bzw. F5) zu drücken, und der Aspire AppHost fährt alle Projekte und Container hoch, lädt die Konfigurationen, und lässt mich meine Microservices und UI’s mit einem Klick debuggen.
Dank Service-Discovery - das ist eine Art dynamisches automatisches Adressbuch weiss jeder Teil der App, wie es die anderen Teile erreicht, ohne dass man sich auf festgelegte IP-Adressen verlassen muss, um die verschiedenen Services mit dem AppHost zu verknüpfen. Ein eindeutiger Name als Text reicht aus. Aspire kümmert sich um den Rest. Das gilt auch für Deployments, die nicht nur auf Azure oder anderen Cloud-Lösungen einfach umzusetzen sind.
Aspire ist für Entwickler ein sehr bequemes Tool, mit dem Entwickler fast ohne Setup verteilte Systeme bauen und erweitern können.
Aspire kann auch in ältere, bereits existierende Systeme integriert werden. Dass dies ein wenig schwieriger ist als ein neues Projekt aufzusetzen dürfte den meisten klar sein, aber für spätere Erweiterungen gibt es derzeit nichts mit dem es einfacher ist neue Projekte und Container hinzuzufügen.
Wie funktioniert .Net Aspire?
Jede Aspire-Lösung kommt mit einem AppHost-Projekt und einem ServiceDefaults Projekt.
ServiceDefaults sind Konfigurationen und Regeln, die für jedes Modul gleich gelten.
AppHost
AppHost ist ein fast ganz normales .Net Projekt und ist der zentrale Punkt in dem konfiguriert werden kann welche externen Container und in der Lösung vorhandenen Projekte (z.B. Microservices) gestartet werden. AppHost kennt diese Projekte, weil AppHost sich von diesen Projekten mittels einer Referenz abhängig macht. Diese Abhängigkeit ist aber völlig in Ordnung und spielt nur für die Entwicklung eine Rolle. Sie ermöglicht, dass dem AppHost all die unabhängigen Module hinzugefügt werden können. Für jedes Modul wird im AppHost ein eindeutiger Name definiert, um es für die ServiceDiscovery - das dynamische Adresssbuch - zu identifizieren.
Bei einer Auslieferung des Programms werden aus dem AppHost alle nötigen Dateien erstellt, die alle Informationen enthalten damit die Applikation als Ganzes mit all ihren einzelnen isolierten und unabhängigen Teilen, funktioniert.
Ohne .Net Aspire müsste man all diese Konfigurationen und Dateien von Hand erstellen und es wäre den Entwicklern nicht möglich die gesamte Applikation mit einem Klick zu starten. Man müsste alle Container selbst laufen lassen, zum Beispiel auf Docker Desktop, und dann den Teil, den man gerade testen oder Fehler finden möchte in einer IDE oder einem Editor wie Visual Studio starten.
Wenn ein Modul dem AppHost hinzugefügt wird, gibt es eine Reihe an Konfigurationsmöglichkeiten. Beispielsweise ob ein Modul ein anderes Modul “sehen” darf. Manchmal muss man einem Modul auch sagen, dass es warten soll, bis ein anderes Modul aufgestartet ist. Das macht beispielsweise beim User Interface - das ist der Teil, den ein Benutzer sieht und mit ihm am Computer interagiert - Sinn. Oft werden beim ersten Start der Applikation schon Daten geladen. Damit dies möglich ist müssen die Module, die auf die Daten zugreifen können, vorher schon laufen.
Im AppHost können Sie bereits existierende externe Container hinzufügen, ohne sie in der .Net Lösung zu integrieren. Es ist also nicht zwingend nötig, gleich den kompletten Umstieg zu machen in der alles in einer .Net Aspire Lösung lebt.
ServiceDefaults
Das ServiceDefaults-Projekt enthält Konfigurationen und Regeln, die für alle Services gleich gelten. Dazu gehören zum Beispiel Regeln die definieren, wie oft ein gescheiterter Aufruf zu einem Modul oder einer externen API nochmal erfolgen soll, und wie die Abstände zwischen diesen wiederholenden Aufrufen geregelt sind. Auch sogenannte Health-Checks und Telemetriedaten sind am besten in den ServiceDefaults, damit jedes Modul ohne sich wiederholende Konfiguration darauf überprüft werden kann, ob ein Modul Probleme wie lange Wartezeiten oder Fehler hat, und ob ein Modul überhaupt noch läuft und erreichbar ist.
Die ServiceDefaults lassen sich für jedes Modul überschreiben, sodass man spezielle Regeln erstellen kann, die nur für ein bestimmtes Modul gelten.
Deployment mit .NET Aspire
Ich habe oft gelesen, dass angenommen wird, dass .Net Aspire Projekte ausschliesslich für Azure funktionieren. Da Aspire .NET-Stack ist, ist natürlich klar, dass es einen Fokus gab, dass Aspire möglichst einfach auf Azure zu deployen ist. Das ist auch ein Vorteil von Aspire, und nicht etwa ein Nachteil. Trotzdem fragt sich dann so mancher zurecht, ob Aspire für Deployments auf eigene Server oder VMs geeignet ist.
Da Aspire am Ende Docker-Container erstellt, können Aspire-Lösungen in jedes Kubernetes-Cluster, Docker Swarm, oder mittels einfachem Docker-Compose auf jedem Server installiert werden. Aspire ist hier vollkommen agnostisch.
Für das Deployment direkt auf Azure kann mit dem Visual Studio Publisher gearbeitet werden, oder auch eine Pipeline genutzt werden.
Wir nutzen Aspirate (oder auch Aspir8) genannt. Aspirate macht Deployments in jedes beliebige Kubernetes-Cluster einfach. Das Cluster muss aber erstmal aufgesetzt und konfiguriert werden. Diese Arbeit lohnt sich nicht immer. Selten, ehrlich gesagt. Aspirate generiert auch Docker-Compose-Files, das aufgrund der AppHost-Konfiguration automatisch generiert wird. Mittlerweile ist das Erstellen von Docker-Compose Files aber auch schon direkt in Aspire integriert.
Zusammenfassend: Egal ob Azure, lokaler Server, eine Virtuelle Maschine: Solange Docker-Container auf dem System laufen, kann mit Aspire gebaut und geliefert werden.
Herausforderungen mit .NET Aspire
.NET Aspire ist noch jung. Entsprechend gibt es Features, die man sich aktuell noch wünscht. Nichts davon ist aber von einer Tragweite die .NET Aspire Projekte problematisch machen. Die Features sind eher für noch mehr Bequemlichkeit.
Da alle Projekte in einer Aspire-Projektmappe enthalten sind, ausser man registriert sie als externe Ressourcen, kann es passieren, dass jemand fälschlicherweise Microservices untereinander direkt referenziert und somit abhängig macht. Das kommt öfters vor, als man vielleicht denkt.
Mit Architekturtests lässt sich dem Vorbeugen. Diese Tests sind ohnehin ein wichtiger Bestandteil, um sicherzustellen, dass die Architektur einer Software langfristig eingehalten wird. Der Trick dabei ist nicht zu restriktiv zu sein, aber klare Leitplanken zu schaffen. Architekturtests sind aber ein Thema für ein anderes Mal
Wie und warum wir .NET Aspire einsetzen
Wir setzen Aspire ein, um unsere Entwicklung zu vereinfachen, sie so zu beschleunigen, und Ihnen Lösungen zu liefern, die Sie bei sich auf eigenen Servern oder bei einem Cloud Anbieter laufen lassen können.
In unseren .Net Aspire Projekten sind alle Module enthalten, damit wir mit einem Klick die Programme erweitern, testen, und verbessern können. Um sicherzustellen, dass die Module isoliert bleiben verwenden wir Architekturtests, die ohnehin jedes Projekt beinhalten sollte, um die Einhaltung der Architektur sicherzustellen.
Und ihre Software-Lösung?
Haben Sie auch eine Software-Lösung im Einsatz, deren Modernisierung sie einmal unverbindlich prüfen lassen wollen? Gerne schauen wir ihre App an und vergleichen sie mit einem Einsatz von .NET Aspire. Melden Sie sich ungeniert über unser Kontaktformular.
