Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 10 Min.

C# – auch in Ihrem Browser

Mit der WebAssembly-Ausgabe von Mono macht C# im Webbrowser erste Gehversuche: lauffähig auf Mobil- und Desktop-Plattformen, ganz ohne Browser-Plug-in.
Das Web ist in den vergangenen Jahren zu einer ernst zu nehmenden Ausführungsumgebung für Client-Anwendungen avanciert.  Zentraler Vorteil ist neben der Plattformunabhängigkeit die besonders einfache Bereitstellung dieses Anwendungstyps. So verwundert es kaum, dass .NET Core bis jetzt noch keine ernst zu nehmende Frontend-Technologie in seinem Lieferumfang enthält – von der kürzlich eingeführten Unterstützung für die Windows Presentation Foundation (WPF) und Windows Forms abgesehen, die aber wieder nur unter Microsoft Windows betrieben werden können (siehe [1]).In der dotnetpro 1/2018 haben wir Ihnen unter [2] bereits drei Möglichkeiten gezeigt, wie Sie C# mit Webtechnologien verknüpfen können, um webbasierte Frontends für moderne Business­anwendungen zu schreiben. Seitdem hat sich die Welt weitergedreht und Microsoft hat Blazor vorgestellt, ein experimentelles Framework des ASP.NET-Core-Teams zur Entwicklung von Single Page Web Applications (SPA), die komplett im Browser laufen. Dabei kommen die .NET-Sprache C# und die von ASP.NET MVC oder ASP.NET Web Pages bekannte Templating-Engine Razor zum Einsatz. Unter der Haube tickt Mono – oder genauer: eine Portierung der Mono-Laufzeitumgebung für WebAssembly.

WebAssembly: Ein Bytecode für das Web

Das technologische Fundament für mono-wasm stellt Web­Assembly (kurz: Wasm) dar, ein Low-Level-Bytecode für das Web. Dieser zeichnet sich durch eine besonders hohe Ausführungsgeschwindigkeit aus. Was die übrigen Entwicklungsziele [3] angeht, ist WebAssembly
  • schnell, effizient und portabel,
  • für den Menschen lesbar und einfach zu debuggen,
  • sicher, weil es derselben Sandbox unterliegt, die auch für die übrigen Webanwendungen gilt,
  • und zudem Teil des offenen, abwärtskompatiblen Web.
Entworfen ist Wasm als Kompilierziel für unterschiedliche Sprachen: Besonders gut geeignet ist der Bytecode aufgrund seines gegenwärtigen Funktionsumfangs für Programme, die in den High-Level-Sprachen C, C++ oder Rust geschrieben sind. Die aktuelle Wasm-Implementierung sieht sich allerdings nur als Minimum Viable Product (MVP), als ersten Wurf mit vielversprechenden Zukunftsaussichten. So sollen in kommenden Fassungen etwa die Unterstützung für Threads oder Garbage Collection, eine Integration in das JavaScript-Modulsystem und einige weitere Features implementiert werden [4]. Wasm ist jedoch explizit nicht als Ersatz für Java­Script gedacht, sondern als sinnvolle Ergänzung, zum Beispiel dort, wo es auf eine besondere Performance ankommt: rechenintensive Algorithmen, Computerspiele oder die Emulation von Computersystemen – Szenarien, die mit Web­Assembly schon heute umgesetzt werden.Unterstützt wird WebAssembly standardmäßig ab den Browserversionen Microsoft Edge 16, Mozilla Firefox 52 (nicht jedoch dessen Extended Support Release), Google Chrome 57 sowie Apple Safari 11.Zur Ausführung gebracht wird Wasm durch ein Stück in Java­Script verfassten Glue Code. Anwendungen, die auf Wasm basieren, können etwa zielgerichtet und vollumfänglich in WebAssembly entwickelt werden, als Team mit einer in JavaScript und HTML geschriebenen Weboberfläche interagieren und als Migrationsstrategie bestehenden Code, seien es kleinere Helferklassen oder komplexe Berechnungsmodule, in den Webbrowser hieven. WebAssembly ist dabei aber keine Plug-in-Lösung à la Silverlight oder Java-Applet, sondern nativ im Webbrowser eingebaut. Der Anwender muss also keine weiteren Abhängigkeiten installieren, um für Wasm geschriebene Programme auszuführen.Um selbst in Kontakt mit dieser Basistechnologie zu kommen, lohnt ein Blick in das von Mozilla getriebene WebAssembly Studio [5], eine webbasierte IDE für Wasm-Anwendungen (siehe Bild 1). WebAssembly Studio basiert auf Monaco, dem Open-Source-Unterbau von Vi­sual Studio Code – selbst übrigens ebenfalls eine Webanwendung. In dieser IDE können Sie mit C, Rust, WAT (der menschenlesbaren Wasm-Repräsentation) oder AssemblyScript (einem Compiler für TypeScript-Anwendungen nach Wasm) ­arbeiten.

Mono: Das Rückgrat der .NET-Cross-Platform-Entwicklung auf dem Client

Die quelloffene .NET-Laufzeitumgebung Mono stellt Microsofts aktuelle Strategie für plattformübergreifend ausführbare Anwendungen dar. So basiert etwa Xamarin, das von Microsoft angebotene Produkt zur Multi-Plattform-Entwicklung über verschiedene mobile Plattformen hinweg, auf ebenjener Laufzeitumgebung. Auch die Spiele-Engine Unity nutzt Mono, um einmal entwickelte Spiele auf unterschiedlichen Plattformen (Mobil, Desktop, Spielekonsolen) bereitstellen zu können. Mit dieser Breite von Plattformen war Miguel de Icaza, Begründer des Mono-Projekts, jedoch noch nicht zufrieden. Denn auf der wohl weitverbreitetsten Plattform, dem Webbrowser, lief Mono noch nicht. So kündete de Icaza im August 2017 an, Mono auch nach WebAssembly und somit in aktuelle Webbrowser zu bringen [6]. Im Blogpost wurden zugleich zwei Prototypen vorgestellt.
  • JiT (Just in Time): Bei diesem Vorgehen wird die auf C (und damit eine der „Referenzsprachen“ für WebAssembly) basierende Mono-Runtime nach WebAssembly kompiliert. Auf dieser Laufzeitumgebung wird anschließend Intermediate-Language-Code (IL) ausgeführt – was jedoch zulasten der Performance geht.
  • AoT (Ahead of Time): Hierbei werden sowohl die Mono-Laufzeitumgebung und die Mono-Klassenbibliotheken als auch der Quellcode des Entwicklers statisch nach Web­Assembly kompiliert – was jedoch deutlich länger dauert.
Grundsätzlich sind beide Ansätze interessant: JiT eignet sich aufgrund der deutlich schnelleren Kompilierungsgeschwindigkeit zum schnellen und iterativen Entwerfen von Prototypen, während AoT sich für den Produktions-Build einer Anwendung eignet, da dank statischer Codeanalyse Optimierungen wie zum Beispiel Tree-Shaking – das Entfernen von garantiert nicht verwendetem Code – angewandt werden können. Doch egal über welchen der beiden Ansätze der C#-Code ausgeführt wird: Dieser läuft im Webbrowser genau so, wie er auch auf dem Desktop oder dem Server auf Mono ausgeführt würde. Zwischenzeitlich hat es der JiT-Prototyp in den Master-Branch des Mono-Repositorys geschafft. [7] Der AoT-Ansatz lebt gegenwärtig noch in einem separaten Repository und hört auf den Namen mono-wasm [8].Im Januar 2018 erschien ein Blogpost von Laurent Sansonetti, der seitens Microsoft für mono-wasm verantwortlich zeichnet. Wenige Tage zuvor wurde ein erstes „Super-Alpha“-Release des Tools veröffentlicht, das derzeit nur unter macOS High Sierra betrieben werden kann. Dabei wird die Build-Pipeline für die statische Kompilierung (AoT) demonstriert, die Bild 2 zeigt. Die Ausführung der einzelnen Kommandos können Sie in Listing 1 nachverfolgen:
Listing 1: Ausführen der AoT-Build-Pipeline
$ mcs -nostdlib -noconfig -r:../../dist/lib/mscorlib<span class="hljs-selector-class">.dll</span> hello<span class="hljs-selector-class">.cs</span> -out:hello<span class="hljs-selector-class">.exe</span> <br/>$ mono-wasm -<span class="hljs-selector-tag">i</span> hello<span class="hljs-selector-class">.exe</span> -o output <br/>$ cp index<span class="hljs-selector-class">.html</span> output <br/>$ ls output <br/>hello<span class="hljs-selector-class">.exe</span>        index<span class="hljs-selector-class">.html</span>        index<span class="hljs-selector-class">.js</span>        index<span class="hljs-selector-class">.wasm</span>        mscorlib<span class="hljs-selector-class">.dll</span>  
  • Der C#-Code des Anwenders (sowie weitere Abhängigkeiten, etwa die mscorlib) wird mithilfe des Mono-C#-Compilers (mcs) in die Intermediate Language (IL) überführt.
  • Das Kommandozeilen-Tool mono-wasm nimmt IL-Assemblies entgegen und überführt diese in Bitcode, der sich zur Weiterverarbeitung durch die Compilerplattform LLVM eignet. Diese besitzt ein Backend zur Ausgabe für Wasm. In das Ausgabeverzeichnis wird am Ende die darüber generierte Binärdatei index.wasm sowie der nötige Glue Code zur Kommunikation mit dem nach Wasm überführten C#-Code in JavaScript (index.js) kopiert, sowie auch der IL-Code.
  • Abschließend wird noch die Datei index.­html als Einsprungpunkt der Website in das Ausgabeverzeichnis kopiert. Das Gesamtprojekt schlägt derzeit noch mit rund 10 MByte Dateigröße zu Buche.
Werfen wir einen Blick in die Quelldateien: Listing 2 zeigt den Inhalt der Datei hello.cs. Diese Datei enthält eine Klasse namens Hello, die eine Main-Methode besitzt. Darüber hinaus existiert eine statische Methode Yell. In der Main-Methode ist ein Array namens hello hinterlegt, das mithilfe der weithin bekannten String-Methode Join zu einem einzelnen String zusammengefasst werden soll. Das Ergebnis soll auf der Konsole über die genauso bekannte Funktion WriteLine ausgegeben werden. Die Methode Yell gibt hingegen die ihr übermittelte Zeichenkette in Großbuchstaben, ergänzt um drei Ausrufezeichen, auf der Konsole aus. Wichtig: Die Main-Methode ruft – gegenwärtig als Hack – die Yell-Methode initial einmal auf, um zu verhindern, dass sie bei der statischen Kompilierung entfernt wird (da es ansonsten keine Referenz auf diese Methode gibt).
Listing 2: Implementierung von hello.cs
<span class="hljs-keyword">using</span> System; <br/><br/><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Hello</span> { <br/>  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>) </span>{ <br/>    <span class="hljs-keyword">var</span> hello = <span class="hljs-keyword">new</span>[] { <span class="hljs-string">"hello"</span>, <span class="hljs-string">"dotnetpro"</span>, <br/>      <span class="hljs-string">"this"</span>, <span class="hljs-string">"is"</span>, <span class="hljs-string">"wasm"</span> }; <br/>    Console.WriteLine(String.Join(<span class="hljs-string">" "</span>, hello)); <br/>    Yell(<span class="hljs-string">"Hack"</span>); <br/>  } <br/>  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Yell</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> text</span>) </span>{ <br/>    Console.WriteLine(<span class="hljs-string">$"<span class="hljs-subst">{</span></span><br/><span class="hljs-string"><span class="hljs-subst">      text.ToUpperInvariant()}</span>!!!"</span>); <br/>  } <br/>}  
Die Main-Methode wird bei Ausführung im Browser initial aufgerufen. Danach besteht in beide Richtungen die Möglichkeit, zu kommunizieren: So ruft Mono das benutzerdefinierte Ereignis WebAssemblyContentLoaded auf, nachdem die Wasm-Anwendung vollständig hochgefahren wurde. Auf dieses kann sich die mit HTML, JavaScript und CSS geschrieben Webanwendung auf Wunsch registrieren.Listing 3 zeigt, wie sich aus JavaScript heraus Methoden aufrufen lassen, die in der WebAssembly enthalten sind: Mit der Methode MonoClass erhält der Aufrufer Zugriff auf eine in der WebAssembly enthaltene Klasse. Der erste Parameter enthält den Namespace – hier eine leere Zeichenkette –, der zweite Parameter den Klassennamen – dies zeigt Zeile 12. War der Zugriff erfolgreich, wird eine von null verschiedene Zahl zurückgeliefert, die als Klassenreferenz dient. Existiert die Klasse nicht, gibt der Methodenaufruf die Zahl null zurück. Mithilfe von MonoMethod kann eine Methode auf dieser Klasse aufgerufen werden (Zeile 13): Dazu wird die Klassenreferenz übergeben, der Name der Zielmethode definiert und im dritten Parameter angegeben, ob die Methode statisch ist oder nicht. In unserem Beispiel ist sie das, daher wird hier true gesetzt. Auch in diesem Fall ist die Rückgabe eine von null verschiedene Methodenreferenz, wenn die Methode aufgelöst werden konnte. Schließlich wird der Methodenaufruf mittels MonoInvoke durchgeführt (Zeile 14): Als erster Parameter kann der Pointer für this angegeben werden, dann folgt die oben aufgelöste Methodenreferenz, dann die Parameteraufzählung. Da es sich um den Aufruf einer statischen Methode handelt, wird der this-Pointer nicht belegt.
Listing 3: Aufruf von Methoden in WebAssembly
01 <span class="hljs-meta"><!DOCTYPE html></span> <br/>02  <span class="hljs-tag"><<span class="hljs-name">head</span>></span> <br/>03    <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>></span> <br/>04    <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> </span><br/><span class="hljs-tag">        <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>></span> <br/>05    <span class="hljs-tag"><<span class="hljs-name">title</span>></span>WebAssembly Example<span class="hljs-tag"></<span class="hljs-name">title</span>></span> <br/>06    <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=</span><br/><span class="hljs-tag">        <span class="hljs-string">"width=device-width, initial-scale=1"</span>></span> <br/>07  <span class="hljs-tag"></<span class="hljs-name">head</span>></span> <br/>08  <span class="hljs-tag"><<span class="hljs-name">body</span>></span> <br/>09    <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> <br/>10    <span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> </span><br/><span class="javascript"><span class="hljs-number">11</span>      <span class="hljs-built_in">document</span>.addEventListener(</span><br/><span class="javascript">          <span class="hljs-string">'WebAssemblyContentLoaded'</span>, () => { </span><br/><span class="javascript"><span class="hljs-number">12</span>        <span class="hljs-keyword">const</span> klass = MonoClass(<span class="hljs-string">''</span>, <span class="hljs-string">'Hello'</span>); </span><br/><span class="javascript"><span class="hljs-number">13</span>        <span class="hljs-keyword">const</span> method = MonoMethod(klass, <span class="hljs-string">'Yell'</span>,</span><br/><span class="javascript">            <span class="hljs-literal">true</span>); </span><br/><span class="javascript"><span class="hljs-number">14</span>        MonoInvoke(<span class="hljs-number">0</span>, method, [<span class="hljs-string">'Hallo'</span>]); </span><br/><span class="javascript"><span class="hljs-number">15</span>      }); </span><br/><span class="javascript"><span class="hljs-number">16</span>    </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> <br/>17  <span class="hljs-tag"></<span class="hljs-name">body</span>></span> <br/>18 <span class="hljs-tag"></<span class="hljs-name">html</span>></span>  
All diese Methoden sowie das benutzerdefinierte Ereignis werden übrigens durch den von mono-wasm bereitgestellten Glue Code in index.js (Zeile 9) definiert. Bild 3 zeigt die Ausführung dieser Anwendung im Webbrowser Google Chrome unter macOS: Zunächst erscheint die aus dem Array hello zusammengesetzte Zeichenkette, dann wird die Methode Yell mit dem Wert Hack aufgerufen, dann aus JavaScript heraus mit der Zeichenkette Hallo, und schließlich werden beide korrekt umgewandelt auf der Konsole ausgegeben.
Doch auch der umgekehrte Weg ist möglich: der Zugriff auf das Document Object Model (DOM) der dargestellten Website aus C# heraus. Mono stellt dazu den Namespace Mono.WebAssembly bereit, der eine einfach zu verwendende Schnittstelle zur Interaktion mit dem DOM verfügbar macht. Auf dem globalen Objekt HtmlPage kann der C#-Entwickler zum Beispiel die Referenz auf das Document-Objekt der Website erhalten, wie Listing 4 zeigt. Dabei wurde die Yell-Methode dergestalt abgewandelt, dass sie das Ergebnis nicht nur auf der Konsole ausgibt, sondern zugleich auch den Inhalt der HTML-Seite dadurch ersetzt (Zeile 10). Die erfolgreiche Ausführung zeigt Bild 4.
Listing 4: Zugriff auf das DOM aus mono-wasm
<span class="hljs-symbol">01 </span><span class="hljs-keyword">using</span> Mono.WebAssembly; <br/><span class="hljs-number">02</span> <span class="hljs-keyword">using</span> <span class="hljs-keyword">System</span>; <br/><span class="hljs-number">03</span> <br/><span class="hljs-number">04</span> public class Hello { <br/><span class="hljs-number">05</span>   // ... <br/><span class="hljs-number">06</span> <br/><span class="hljs-number">07</span>   public static void Yell(string text) { <br/><span class="hljs-number">08</span>     var yelled = $<span class="hljs-string">"{text.ToUpperInvariant()}!!!"</span>; <br/><span class="hljs-number">09</span>     Console.WriteLine(yelled); <br/><span class="hljs-number">10</span>     HtmlPage.Document.Body.InnerText = yelled; <br/><span class="hljs-number">11</span>   } <br/><span class="hljs-number">12</span> }  

Blazor: .NET im Browser

Die obigen Beispiele sind tatsächlich eher unspektakulär. Für uns als .NET-Entwickler stellt sich schließlich die Frage, welcher Mehrwert auf Basis dieser Technologie generiert werden kann. Microsoft selbst liefert mit seinem Experiment Blazor die Steilvorlage: Blazor ist ein Framework zur Implementierung von Single Page Applications (SPA). Der Name des Projekts rührt von der Idee „Razor im Browser“ her. Ganz im Gegensatz zu gängigen SPA-Frameworks wie Angular, Vue.js oder React wird die Logik hier allerdings nicht in JavaScript (oder einer darauf aufbauenden Sprache wie TypeScript) entwickelt, sondern in C#. Die Views wiederum schreibt man nicht in reinem HTML, sondern mithilfe der Templating-Engine Razor.Unter der Webadresse [9] können Sie Blazor direkt in Ihrem (entsprechend modernen) Browser ausprobieren – wohlgemerkt ohne Installation irgendeines Plug-ins, wie Sie es aus Java-Applet-, Flash- oder Silverlight-Zeiten noch gewohnt sein mögen. Natürlich funktioniert das auch auf gängigen Mobilgeräten mit aktueller Software. Da die Anwendung ein Responsive Design umsetzt, lässt sie sich auch auf Mobilgeräten sinnvoll bedienen Die Ausführung dieser Beispielanwendung zeigt Bild 5.
Unter der Haube scheint Mono durch: Wenn Sie in den Entwickler-Tools von Google Chrome (zu öffnen mit der Tastenkombination [F12] unter Windows und Linux sowie [Wahl Befehl I] unter macOS) in der Registerkarte Network den Netzwerkverkehr inspizieren, sehen Sie, wie die einzelnen .NET-Assemblies zur Ausführung durch die Mono-Runtime in WebAssembly heruntergeladen werden. Der Anblick ist dann wirklich nichts für schwache Nerven: In Bild 6 ist zu sehen, wie die Assembly System.IO.dll heruntergeladen wird – als ausführbare Datei inklusive MZ-Header und mit dem altbekannten Hinweis „This program cannot be run in DOS ­mode“. Und recht soll die Assembly behalten, denn im Browser funktioniert es allemal. Details zu Blazor haben wir Ihnen ebenfalls in dotnetpro 1/2018 vorgestellt [10].
FazitBlazor und Mono auf WebAssembly stehen beide noch am Anfang ihrer Entwicklung. Noch sind die entstehenden Applikationsbündel viel zu groß und die Kompilier- und Startzeiten viel zu langsam. Aber dennoch: WebAssembly schlägt zum ersten Mal eine ernst zu nehmende Brücke von .NET ins Web, die plattformübergreifend auf allen Geräten betrieben werden kann, solange ein halbwegs moderner Browser darauf läuft – ganz ohne Abhängigkeiten, ganz ohne Plug-in, mit dem vollen Funktionsumfang, der Webanwendungen schon heute zur Verfügung steht.Dies eröffnet interessante Migra­tions­strategien für bestehenden Quelltext und öffnet die Web-Welt auch denjenigen Entwicklern, die sich bisher noch nicht an Java­Script herangetraut haben.Noch ist Blazor nur ein Experiment, doch hat die Entwicklerszene auf das Framework bislang überaus positiv reagiert. Wird Blazor zum Produkt, so erhalten auch die Basistechnologien wie die WebAssembly-Ausgabe von Mono entsprechenden Auftrieb. Doch unabhängig davon zeigt sich einmal wieder, dass das Web die Plattform zur Entwicklung von Anwendungen geworden ist – mit WebAssembly als einer Inno­vation unter vielen.

Fussnoten

  1. Holger Schwichtenberg, Die Rückkehr des Desktops, dotnetpro 9/2018, Seite 8 ff., http://www.dotnetpro.de/A1809NETCore
  2. Christian Liebel, Im Client (fast) angekommen, dotnetpro 1/2018, Seite 10 ff., http://www.dotnetpro.de/A1801WebSharp
  3. WebAssembly 1.0, https://webassembly.org
  4. WebAssembly – Features to add after the MVP, http://www.dotnetpro.de/SL1810Wasm1
  5. WebAssembly Studio, https://webassembly.studio
  6. Miguel de Icaza, Hello WebAssembly, http://www.dotnetpro.de/SL1810Wasm2
  7. Mono-Repository auf GitHub, http://www.dotnetpro.de/SL1810Wasm3
  8. mono-wasm auf GitHub, https://github.com/lrz/mono-wasm
  9. Blazer-Demo für den Browser, https://blazor-demo.github.io
  10. Jürgen Gutsch, C#-Code im Browser ausführen, dotnetpro 1/2018, Seite 16 ff., http://www.dotnetpro.de/A1801Blazor
  11. TeaVM, http://teavm.org
  12. Cheerp, https://www.leaningtech.com/cheerp

Neueste Beiträge

DWX hakt nach: Wie stellt man Daten besonders lesbar dar?
Dass das Design von Websites maßgeblich für die Lesbarkeit der Inhalte verantwortlich ist, ist klar. Das gleiche gilt aber auch für die Aufbereitung von Daten für Berichte. Worauf besonders zu achten ist, erklären Dr. Ina Humpert und Dr. Julia Norget.
3 Minuten
27. Jun 2025
DWX hakt nach: Wie gestaltet man intuitive User Experiences?
DWX hakt nach: Wie gestaltet man intuitive User Experiences? Intuitive Bedienbarkeit klingt gut – doch wie gelingt sie in der Praxis? UX-Expertin Vicky Pirker verrät auf der Developer Week, worauf es wirklich ankommt. Hier gibt sie vorab einen Einblick in ihre Session.
4 Minuten
27. Jun 2025
„Sieh die KI als Juniorentwickler“
CTO Christian Weyer fühlt sich jung wie schon lange nicht mehr. Woran das liegt und warum er keine Angst um seinen Job hat, erzählt er im dotnetpro-Interview.
15 Minuten
27. Jun 2025
Miscellaneous

Das könnte Dich auch interessieren

UIs für Linux - Bedienoberflächen entwickeln mithilfe von C#, .NET und Avalonia
Es gibt viele UI-Frameworks für .NET, doch nur sehr wenige davon unterstützen Linux. Avalonia schafft als etabliertes Open-Source-Projekt Abhilfe.
16 Minuten
16. Jun 2025
Mythos Motivation - Teamentwicklung
Entwickler bringen Arbeitsfreude und Engagement meist schon von Haus aus mit. Diesen inneren Antrieb zu erhalten sollte für Führungskräfte im Fokus stehen.
13 Minuten
19. Jan 2017
Bausteine guter Architektur - Entwurf und Entwicklung wartbarer Softwaresysteme, Teil 2
Code sauberer gestalten anhand von wenigen Patterns und Grundhaltungen.
6 Minuten
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige