.NET-Anwendungen mit Microservices behutsam migrieren

Schön wäre es, eine Anwendung immer "auf der grünen Wiese" beginnen zu können. Unter wirtschaftlichen und zeitlichen Aspekten ist gerade beim Erweitern von Legacy-Anwendungen ein solcher Neustart jedoch unverhältnismäßig. Hier sind andere Strategien erforderlich.

Architektur/Methoden  –  2 Kommentare
.NET-Anwendungen mit Microservices behutsam migrieren
Anzeige

Hat man noch vor wenigen Jahren unter Legacy-Anwendungen hauptsächlich Altanwendungen auf Großcomputern verstanden, sind inzwischen auch viele PC-Applikationen in die Jahre gekommen. Fasst man den Begriff etwas weiter, lassen sich damit alle Anwendungen zusammenfassen, die aus dem berühmten "historisch" gewachsenen Code bestehen und irgendwann kaum mehr wartbar sind. Mangels oder aufgrund verwaschener Architektur bestehen viele Abhängigkeiten, häufig entgegen der gedachten Richtung oder gar zirkulär.

Business-Logik, GUI, Datenbankanbindung und sonstige Services sind untrennbar miteinander verwoben. Eine kleine Änderung kann unerwartete Auswirkungen an anderer Stelle bewirken, und so trauen sich kaum noch Entwickler daran. Wenn nun aber dennoch größere Erweiterungen anstehen, ist über alternative Vorgehen nachzudenken.

In einigen Fällen besteht die Chance, die Anwendung inklusive der neuen Features von Grund auf neu zu designen. So lässt sich von Anfang an eine klare Struktur definieren und auf aktuelle Techniken setzen. Für Entwickler ist das oft der schönste Weg, und häufig ist zu beobachten, dass Anwendungen einfach weggeschmissen und neu erstellt werden. Unter wirtschaftlichen oder zeitlichen Aspekten ist das jedoch nicht immer sinnvoll. Hier sind gegebenenfalls andere Strategien in Erwägung zu ziehen.

Eine Möglichkeit ist beispielsweise, neue Features als eigenständige Applikationen zu erstellen und sie über definierte Schnittstellen anzusprechen. Eine solche Anwendung wird heutzutage gerne als Microservice bezeichnet. Trotz ihres aktuellen Hypes verbergen sich dahinter keine neue Techniken. Bereits vor Jahren kam die Idee der serviceorientierten Architektur (SOA) auf. Laut Eberhard Wolff spielt die Größe der Applikation beim Microservice keine Rolle [1]. Ein solcher Dienst lasse sich mit unterschiedlichen Sprachen und Techniken realisieren – selbst mit SOAP. Als Abgrenzung zu SOA sieht Wolff den Verzicht auf eine aufwendige Service-Orchestrierung und -Verzeichnisstruktur.

Der Autor schildert in diesem Artikel den Fall einer Applikation, die unter anderem um die Dienste einer zweiten (bestehenden) erweitert wurde. Hier kam bereits lange vor dem Microservice- Hype ein Webservice zum Einsatz – ohne Registry und Orchestrierung. Diese Bemerkung soll aufzeigen, dass sich Microservices hervorragend mit Legacy-Code kombinieren lassen.

Die Applikation war vornehmlich als Viewer für Kundendaten im Einsatz. Im Wesentlichen konnten Anwender einige Selektionskriterien angeben und erhielten dann unterschiedliche Kennzahlen und Daten in thematisch aufgeschlüsselten Registern präsentiert. Kombiniert war das Ganze mit Reporting-Funktionen. Die Applikation sollte insofern verändert werden, dass Anwender nun deutlich umfangreichere Auswahlmöglichkeiten erhalten. Diese sollten dynamisch mit Kennzahlen (z. B. Anzahl der erwarteten Kundensätze) gestützt werden, die von bereits getätigten (Teil-)Selektionen abhängig waren. Zahlreiche neue thematisch sortierte Auswertungen sowie Dialoge zum Erfassen von Daten und die Anbindung an andere Software waren weitere Anforderungen. Die Menge der neuen Features sprach für eine Neuentwicklung. Während einige nicht zeitkritisch waren, sollten andere zeitnah zu nutzen sein. Das war wiederum nur durch eine Integration in die bestehende Applikation möglich.

Es handelte sich um eine Visual-Basic-Applikation, die zwar in das Zeithalter von .NET hinübergerettet worden, aber kaum noch wartbar war: Mit Visual Studio ist es einfach, grafische Benutzeroberflächen zu entwickeln. Schlicht ein Steuerelement auf das Zielfenster ziehen, positionieren – fertig. Ein Klick auf das Element erzeugt den passenden Ereignis-Handler, Code ergänzt – wiederum fertig. Doch genau hier liegt das Problem: Wer so arbeitet, hat schnell eine kleine Applikation zusammengeklickt, und alles liegt in einem Formular, einer Klasse.

Sonderheft "Altlasten im Griff"

Mehr Artikel zum Thema Legacy-Code sind im Sonderheft iX Developer 01/2017 zu finden, dass sich unter anderem im heise Shop erwerben lässt.

Es erfordert schon ein wenig Disziplin, GUI und Verarbeitungslogik voneinander zu trennen. Die ursprünglichen Entwickler des Viewers hatten diese anscheinend nicht und sind – wie so viele andere – in die Falle getappt. Irgendwann ist die Klasse zu groß, besonders wenn weitere Logik – im vorliegenden Fall das Reporting – mal einfach schnell mit hineingepackt wird. Während die gesamte Applikation mit rund 21.000 Zeilen sowie ein paar Hundert Zeilen SQL-Stored-Procedures eher klein ausfiel, war das größte Formular im Laufe der Zeit auf über 6000ˇZeilen angewachsen und kaum noch durchschaubar.

Die Anwendung wurde ständig gebraucht, ebenso einige der geplanten Features. Eine Neuentwicklung kam daher aus Zeitgründen nicht in Frage. Dennoch war das Ziel, das bestehende Programm in eine neue Applikation zu überführen. Weiterhin sollte eine andere, bestehende Funktionalität eingebunden werden. Sie war Teil eines in Java entwickelten Prozesses. Darüber hinaus existierten weitere kleine bis mittelgroße Anwendungen, die in C# erstellt worden waren. Da sowohl Java als auch C# ihre Wurzeln im C-Umfeld haben und sich so über weite Teile ähneln, wurde der Beschluss gefasst, auf diese beiden Sprachen zu konsolidieren.

Anzeige