© S&S Media
Migration gewachsener Anwendungen mit CefSharp

Aus Alt mach Neu - Stück für Stück


Ein Szenario, das uns Softwareentwicklern wohlbekannt ist: Man hat ein Produkt, in dem viele Jahre wertvolle Entwicklungsarbeiten stecken. Die Technologie, mit der man damals angefangen hat, ist mittlerweile in die Jahre gekommen. Doch was nun? Ein Neuschreiben der Anwendungen in einem modernen HTML5-Cross-Plattform-Technologiestack kann möglicherweise lange dauern. Aber wer sagt, dass man alles auf einmal neu entwickeln muss? Oftmals wäre es eher wünschenswert, nur die neuen Teile der Anwendung in HTML5 zu schreiben und in die bestehende Anwendung einzubetten, inklusive Nutzung bestehender Services zur Datenverarbeitung. Wie das geht? Das Chromium Embedded Framework (CEF) kann hier eine Antwort sein.

Das Chromium Embedded Framework (CEF) ist ein Open-Source-Framework [1], das auf dem Kern des Chromium-Browsers basiert. Es bietet die Möglichkeit, einen Browser in eine bestehende Anwendung einzubetten, sodass in der Anwendung eine HTML5-App bereitgestellt werden kann. CEF selbst ist ein C++-Projekt und kann einfach in C++-Anwendungen integriert werden. Daneben gibt es weitere so genannte Bindings für andere Programmiersprachen, wie z. B. .NET (CefSharp [2]), Java (Java Chromium Embedded), Delphi (DCEF 3) und weitere. Diese Bindings bringen CEF in die jeweilige Programmiersprache und -plattform. Neben der Anzeige einer HTML5-App bietet CEF auch die Möglichkeit zur bidirektionalen Kommunikation an. Das bedeutet, dass die eingebettete HTML5-App mit der darunterliegenden Anwendung kommunizieren kann und diese auch mit der HTML5-App. Das ermöglicht eine nahtlose Integration und Kommunikation. Auch Anwendungen, die man täglich einsetzt, nutzen CEF – oftmals ohne dass wir etwas davon merken. Das sind beispielsweise Anwendungen wie Adobe Creative Cloud, Evernote, Spotify oder der Steam-Client, aber auch Spiele wie Mine­craft, League of Legends oder PokerStars integrieren CEF.

Die Motivation hinter der Einbettung

Doch was ist überhaupt die Motivation, einen Web­browser mit einer HTML5-App in eine bestehende Anwendung zu integrieren? Wie eingangs erwähnt, spielt hier das Szenario der Migration eine große Rolle. Bestehende Anwendungen benötigen oftmals Jahre, um in einem neuen Technologiestack entwickelt zu werden. In dieser Zeit müsste man parallel zwei Varianten der Anwendung betreuen und weiterentwickeln. Das kostet eine Menge Ressourcen, die man selten zur Verfügung hat. Mit CEF können wir eben genau den Mittelweg gehen: Neue Teile der Anwendung werden direkt im neuen HTML5-Technologiestack entwickelt, während alte Teile sukzessive nachgezogen werden. Im Laufe der Zeit wird die alte Anwendung mehr und mehr durch die HTML5-App abgelöst, sodass diese in absehbarer Zeit vollständig im neuen Technologiestack vorhanden ist. Ab diesem Zeitpunkt kann auch eine schlankere Alternative wie Electron [3] genutzt werden, um die Anwendung weiterhin als echte Desktopanwendung bereitzustellen.

CefSharp im Einsatz

Für die Simulation einer möglichst alten Anwendung werden wir die guten alten WinForms ausgraben. Als Beispiel werden wir eine kleine Kundenverwaltung entwickeln. Im ersten Schritt werden wir ein Formular mit einer Liste, zwei Eingabefeldern für Vor- und Nachname sowie einen Button erzeugen, um diesen Namen in die Liste einzufügen. Ein Klick auf einen Namen in der Liste wird den Namen in den Eingabefeldern anzeigen. Dahinter wird ein Service liegen, der diese Daten verwaltet. Im zweiten Schritt werden wir die Liste mit CefSharp austauschen. Darin soll eine HTML5-App laufen, die die Liste anzeigt und auf Eingabe von außen reagieren kann. Sie soll als Integrationspunkt den bereits bestehenden Service der WinForms-Anwendung nutzen.

Diese Art der Integration ist oftmals der erste Weg in Richtung HTML5-Oberflächen. Die bestehende – und getestete – Funktionalität bleibt durch den WinForms-Service bestehen, während das Frontend modernisiert wird. In einem weiteren Schritt kann man den WinForms-Service gegen einen JavaScript-basierten Service austauschen und die ganze Anwendung somit in die moderne HTML5-Welt portieren. Der Code für das Beispiel in Listing 1ist auf GitHub zu finden [4].

Die guten alten WinForms

Zum Entwickeln der WinForms-Applikation erstellen wir in Visual Studio ein neues WinForms-Projekt mit .NET 4.5. Neben dem standardmäßig erzeugten Formular benötigen wir noch eine zusätzliche Datei mit dem Namen CustomerService.cs. Die Implementierung ist in Listing 1 zu finden.

Listing 1: „CustomerService.cs“

namespace CustomerManagement { public class Customer { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } public class CustomerService { private readonly ICollection<Customer> _customers = new List<Customer>(); private int _id; public event EventHandler ItemAdded; public void Add(string firstName, string lastName) { _customers.Add(new Customer() { Id = ++_id, FirstName = firstName, LastName = lastName }); OnItemAdded(); } public Customer Get(int id) { return _customers.FirstOrDefault(c => c.Id == id); } public ICollection<Customer> List() { return _customers; } protected virtual void OnItemAdded() { ItemAdded?.Invoke(this, EventArgs.Empty); } } }

Die Implementierung besteht aus zwei Klassen. Die erste Klasse Customer beschreibt unser Kundenmodell, das aus einer ID, einem Vornamen und einem Nachnamen besteht. Die zweite Klasse CustomerService ist ein einfacher Service, um eine Liste von Customer zu organisieren. Der CustomerService bietet drei öffentliche Methoden an:

  • Add(string, string): Fügt der internen Liste einen neuen Kunden hinzu und löst daraufhin das Event ItemAdded aus. Als Parameter akzeptiert die Methode zwei Strings für den Vor- und Nachnamen.

  • Get(int): Liefert einen einzelnen Kunden anhand seiner ID zurück.

  • List(): Liefert alle Kunden zurück.

Aufhübschen

Als Nächstes erstellen wir das User Interface (UI), sodass man mit dem eben entwickelten Service interagieren kann. Dazu benötigen wir

  • eine Listbox (Name: customers)

  • zwei Textfelder (Namen: firstName und lastName)

  • zwei Labels mit den Beschriftungen First name: und Last name

  • einen Button mit der Beschriftung Add customer

In Abbildung 1 ist die Anordnung der UI-Komponenten zu sehen. Die in der Liste angegeben Namen geben den Namen der Komponente an, mit dem sie nachher im Code anzusprechen ist.

rauber_cef_1.tif_fmt1.jpgAbb. 1: Die WinForms-Anwendung

Im Code-B...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang