Kolumne: Stropek as a Service

Die erste Preview von ASP.NET Blazor bringt C# wieder in den Browser
Keine Kommentare

So wie viele andere Personen in der Softwareentwicklung auch, habe ich das Programmieren mit Sprachen wie C++, Java und vor allem C# gelernt. Ich mag daher typisierte Sprachen, und mir sind die Vorteile einer vollwertigen IDE im Vergleich zu einem leichtgewichtigen Editor mit Konsole bewusst.

Dementsprechend habe ich mich von Anfang an in JavaScript nicht ganz wohl gefühlt. Zugegeben, es ist eine spannende Programmiersprache, die ihre Mächtigkeit erst auf den zweiten Blick zeigt. JavaScript lädt zum Tüfteln ein. Aber JavaScript für große, professionelle Projekte – naja, nicht so mein Ding. TypeScript hat meine Einstellung zu clientseitiger Webentwicklung geändert. Diese Sprache bietet mir das Beste aus beiden Welten. Am Ende des Tages läuft es aber genauso auf JavaScript hinaus. Um gut TypeScript zu programmieren, muss man solides JavaScript-Wissen haben. Ansonsten verzweifelt man recht schnell, wenn es gilt, die ersten Probleme in größeren Anwendungen zu beheben. Ohne JavaScript geht clientseitige Webentwicklung also nicht, oder?

Mein Outing: Ich mochte Silverlight

Jetzt ist es raus. Ich fand einiges an Silverlight nicht schlecht. Vor allem C# im Browser übt großen Reiz auf mich aus. Es ist eine moderne, weit verbreitete Programmiersprache, die kontinuierlich weiterentwickelt wird, sie ist Open Source und auf praktisch allen Plattformen verfügbar, mit Visual Studio und Visual Studio Code stehen sowohl eine mächtige IDE als auch ein schlanker Editor zur Verfügung – das sind nicht zu vernachlässigende Vorteile. Dazu kommt, dass eine einheitliche Sprache und Base Class Library für Server und Client die Entwicklungsproduktivität enorm steigern. Stimmt schon, dass man das auch mit Node.js und TypeScript schafft. Ich habe Node.js in den letzten Jahren kennen und mögen gelernt. Auf die häufig fehlenden oder schlecht gewarteten TypeScript Type Definitions kann ich aber gut und gerne verzichten. Da ist mir mein serverseitiges ASP.NET Core bei großen Projekten schon lieber.

Die größte Schwäche von Silverlight war, dass es nicht auf einem offenen Browserstandard aufgebaut war, sondern ein Plug-in braucht. Dementsprechend ging Silverlight mit dem Verbannen von Plug-ins durch Browser- und Plattformhersteller unter. Neben der Notwendigkeit eines Plug-ins gab es noch andere, häufig kritisierte Punkte: Warum mit XAML eine eigene Markup-Sprache, es gibt doch HTML? Warum eine eigene Styling- und Templatelogik, man könnte doch CSS nehmen? Trotz guter Ansätze scheiterte Silverlight, und das Monopol von JavaScript im Browser blieb aufrecht.

Auftritt WebAssembly

Im März 2017 tat sich etwas Fundamentales in der Webwelt: Das erste Minium Viable Product (MVP) von WebAssembly erschien. Damit ist der Startschuss für einen ernsthaften Konkurrenzkampf mit JavaScript gefallen. Was macht WebAssembly (kurz Wasm) aus?

  • Das Beste gleich zu Beginn: Wasm wird von der W3C vorangetrieben und wird ohne Plug-in von allen führenden Browsern (Chrome, Edge, Firefox und WebKit) auf Desktop und Mobilplattformen unterstützt.
  • Es ist ein binäres Format für eine virtuelle Maschine. Sprachen wie C++ können in Wasm übersetzt werden.
  • Wasm wurde nicht ausschließlich für den Browser konzipiert, sondern kann generell als Standard für portablen Code genutzt werden. In diesem Artikel beschränken wir uns aber auf Wasm im Browser.
  • Im Browser kann Wasm JavaScript aufrufen und umgekehrt.
  • Wasm ist bei der Ausführung so schnell wie nativer Code.
  • Es gibt ein Textformat für Wasm, damit man mit dem Code leichter umgehen kann und Debuggingunterstützung hat.
  • Wasm wird in einer Sandbox ausgeführt, die speziell im Browser für die notwendige Sicherheit sorgt. Die Sandbox kann auch auf JavaScript basieren. Wer gar nicht anders kann, erreicht daher mit Wasm auch den Internet Explorer.

Mono mit Blazor auf Wasm

C++ kann wie erwähnt in Wasm kompiliert werden, der Großteil aller weit verbreiteten Programmiersprachen ist auf unterster Ebene in C++ geschrieben, der Sturm auf den Browser ist also eröffnet. C# ist dabei an vorderster Front dabei. Das Mono-Team hat bereits im August 2017 erste Prototypen veröffentlicht, die zeigen, wie C# und .NET auf Wasm laufen. Natürlich sind Programmiersprache und Basisbibliothek noch zu wenig, um in der Praxis größere Weblösungen zu bauen. Genau diese Lücke schließt das Blazor-Projekt.

Ich kenne eine Menge .NET-Entwicklungsteams, die schon lange darüber nachdenken, wie sie mit ihren weit verbreiteten WinForms-, WPF- und Xamarin-Anwendungen ins Web kommen. Hat man ein größeres Entwicklungsteam mit viel Erfahrung in diesen Technologien und eine Menge bestehenden Code, wechselt man nicht so mir nichts, dir nichts auf z. B. TypeScript mit Angular. Blazor ändert in solchen Situationen die Spielregeln.

  • HTML und CSS muss immer noch gelernt werden, das C#-, .NET- und Toolwissen ist aber weiter anwendbar.
  • Bestehender Code (z. B. Businesslogik, Formvalidierung, eventuell sogar Teile der View-Logik) kann im Browserclient wiederverwendet werden.
  • Die üblichen Mechanismen für Modularisierung (Projekte, DLLs, NuGet-Pakete) funktionieren wie gewohnt.

Neugierig? Dann lassen Sie uns kurz einen Blick darauf werfen, wie Blazor das Kunststück schafft, C#, .NET und den Browser zu vereinen.

Blazor = Broser + Razor

ASP.NET Blazor verbindet Wasm, die Mono-Plattform und Razor, die Markup-Sprache für dynamisches HTML aus ASP.NET Core. Code schreibt man in C#. Für das UI gibt es im Gegensatz zu Silverlight keine eigene Sprache, sondern es werden HTML und CSS verwendet. Für die Leserinnen und Leser, die noch nie mit Razor gearbeitet haben, habe ich in Listing 1 ein einfaches Codebeispiel zusammengestellt. Ich werde in diesem Artikel nicht auf Details eingehen, der Code soll nur einen Eindruck über das prinzipielle Vorgehen vermitteln. Im Windows Developer 7.18 und auf der kommenden BASTA! 2018 folgen ausführliche Einführungen in das Programmieren mit Blazor.

@page "/"
@using RestApi.Shared
@inject HttpClient Http

<h1>Customer List</h1>

<button @onclick(async () => await FillWithDemoData())>Fill with demo data</button>

@if (Customers == null)
{
  <p><em>Loading...</em></p>
}
else
{
  <table class='table'>
    <thead>
      <tr>
        <th>ID</th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Department</th>
      </tr>
    </thead>
    <tbody>
      @foreach (var customer in Customers)
      {
        <tr>
          <td>@customer.ID</td>
          <td>@customer.FirstName</td>
          <td>@customer.LastName</td>
          <td>@customer.Department</td>
        </tr>
      }
    </tbody>
  </table>
}
@functions {
  private Customer[] Customers { get; set; }

  protected override async Task OnInitAsync() =>
    await RefreshCustomerList();

  private async Task RefreshCustomerList()
  {
    Customers = await Http.GetJsonAsync<Customer[]>("/api/Customer");
    // Trigger UI refresh
    StateHasChanged();
  }

  private async Task FillWithDemoData()
  {
    for (var i = 0; i < 10; i++)
    {
      await Http.SendJsonAsync(HttpMethod.Post, "/api/Customer", new Customer
      {
        FirstName = "Tom",
        LastName = $"Customer {i}",
        Department = i % 2 == 0 ? "Sales" : "Research"
      });
    }

    await RefreshCustomerList();
  }
}

Da Wasm im Moment noch nicht direkt auf die Browser- und DOM-APIs zugreifen kann, besteht Blazor aus einem .NET- und einem JavaScript-Teil. Wann immer Blazor mit einem Browser-API interagieren muss (z. B. das DOM zur Laufzeit verändern, einen HTTP Request abschicken), übergibt der Wasm-Teil von Blazor an den JavaScript-Teil.

In Abbildung 1 sieht man die Struktur von Blazor. Das Bild zeigt das Netzwerklog beim Laden einer Blazor-Beispielanwendung. Als Erstes werden die JavaScript-Teile von Blazor und Mono geladen. Sie beginnen mit dem Bootstrap-Prozess von Blazor. Als Nächstes lädt der Browser die Mono-Wasm-Laufzeitumgebung. Sie holt danach die notwendigen .NET-DLLs (eigene Anwendung und benötigte Framework-DLLs) vom Webserver. Die DLLs sind ganz normale .NET-Standard-DLLs wie man sie aus jeder anderen .NET-Core-Anwendung kennt. Die Mono Wasm Runtime interpretiert die .NET DLLs im Moment. Sie werden in der vorliegenden, ersten Preview von Blazor nicht in Wasm kompiliert. Das Blazor-Team hat auf GitHub erwähnt, dass bereits daran gearbeitet wird, sowohl Interpretation als auch Ahead-of-Time-Kompilieren (AoT) zuzulassen.

Abb. 1: Laden einer Blazor-Beispielanwendung

Abb. 1: Laden einer Blazor-Beispielanwendung

Abbildung 2 zeigt, wie JavaScript, Wasm und .NET beim Behandeln eines Button-Click-Ereignisses zusammenspielen. Code im JavaScript-Teil von Blazor (BrowserRenderer.ts) reagiert auf den DOM-Event. Er übergibt den Event an die Mono Wasm Runtime, die den entsprechenden .NET-Code ausführt. Das Ergebnis, der sogenannte Render Batch, wird von Mono Wasm an JavaScript zurückgegeben. JavaScript ist für das Durchführen der notwendigen DOM-Änderungen, also für das Aktualisieren der Benutzerschnittstelle, verantwortlich.

Abb. 2: Ablauf eines Button-Clicks in Blazor

Abb. 2: Ablauf eines Button-Clicks in Blazor

Wo steht Blazor?

Wer an dieser Stelle begeistert ist und plant, sofort die Entwicklungsstrategie in Richtung Blazor zu verschieben, den möchte ich bremsen. Blazor ist ein experimentelles Projekt, und es gibt gerade einmal eine erste Public Preview. Man muss im Moment das System sogar noch selbst kompilieren und kann keine fertige Visual-Studio-Erweiterung herunterladen.

Die Webwelt mit ihrer rasanten Entwicklungsgeschwindigkeit und unsere Erfahrungen mit Silverlight haben uns gelehrt, entspannt an neue Entwicklungen heranzugehen und nicht zu schnell das Ruder herumzureißen. Jetzt ist die richtige Zeit, um mit Blazor zu experimentieren, Feedback zu geben, mitzuarbeiten (Blazor ist Open Source, das Team akzeptiert gerne Pull Requests und GitHub Issues) und die Auswirkungen auf die zukünftige Architektur der eigenen Projekte abzuschätzen.

Da die Dokumentation zu Blazor im Moment nur aus ein paar versprengten Blogartikeln besteht, habe ich die kostenlose Communitywebseite begonnen, die beim Einstieg in Blazor helfen soll.

Wasm als die Zukunft der Webentwicklung?

Meiner Meinung nach ist WebAssembly eine wertvolle Ergänzung in der Webentwicklung. Macht es JavaScript obsolet? Keineswegs. Wie oben gezeigt, arbeiten Wasm und JavaScript Hand in Hand. Das Monopol von JavaScript als Programmiersprache im Browser bricht Wasm aber auf jeden Fall auf. Als Entwickler werden wir die Sprachen und Plattformen weiter nutzen können, in denen wir viel Erfahrung und bestehenden Code mitbringen.

Wie sehr sich die Browserentwicklung von JavaScript weg hin zu Wasm verschieben wird, ist schwer abzuschätzen. Das hängt nicht zuletzt davon ab, wie die neue Technologie von uns Entwicklerinnen und Entwicklern angenommen wird. Microsoft hat auf jeden Fall Gefallen an Wasm gefunden. Blazor ist nicht das einzige Wasm-bezogene Projekt, das der Konzern aus Redmond vorantreibt. Auch die Xamarin-Community zeigt schon Prototypen von Xamarin Forms mit Wasm im Browser. Eine spannende Zeit mit ganz neuen Möglichkeiten kommt auf uns zu!

Lesen Sie alle Ausgaben der Kolumne „Stropek as a Service„!
In der Kolumne greift Rainer Stropek spannende Aspekte wie die Finanzierung, den Customer Lifetime Value, aber auch wichtige Themen wie Billing, Kundenbindung durch Qualität oder APIs auf – alles aus der Sicht eines Unternehmers, der seit 20 Jahren in der IT-Branche tätig ist und seit fünf Jahren intensive Erfahrungen mit SaaS gesammelt hat.
Unsere Redaktion empfiehlt:

Relevante Beiträge

X
- Gib Deinen Standort ein -
- or -