Hallo, mein Name ist Christoph Jahn. Ich bin ein Softwareentwickler und Fotograf aus Leipzig.

ASP.NET vNext mit dem Mac entwickeln

2014-11-02

Ab der kommenden Version von Microsofts ASP.NET werden offiziell MacOS und Linux als Entwicklungssysteme mit unterstützt. Ich möchte euch hier kurz vorstellen, wie man seinen Rechner dafür einrichtet und eine ASP.NET MVC6 Seite unter MacOS X erstellen kann.

Gleich vorab: Es ist noch nicht mal ansatzweise für einen produktiven Betrieb geeignet. Am Ablauf und den APIs wird sich noch sich noch sehr viel ändern und der Alphastatus als solcher ist durchaus ernst gemeint. Trotzdem macht es schon jetzt viel Spass, ein wenig mit dem Projekt zu spielen.

Formalitäten

Im Folgenden wird hier eigentlich andauernd —- sogar bei der späteren Entwicklung — eine Internetverbindung benötigt. Bei der Installation muss eine Menge heruntergeladen werden und auch danach erhalten wir neue DotNet-Pakete erstmal nur häppchenweise über das Netz. Für „mal-schnell-unterwegs-ausprobieren“ ist der Text hier also nicht geeignet. Nehmt euch also ein Stündchen Zeit, stellt das Handy auf „nerv-nicht-halt-die-klappe“ und lasst euch DotNET am Mac zeigen.

Der Inhalt des Textes ist eine Momentaufnahme und bildet den aktuellen Stand der Technik ab. Da sich viele Dinge noch ändern, kann es sein, dass ein paar der Quelltexte später nicht mehr genau so funktionieren, wie sie hier gezeigt wurden. Ich versuche den Text aktuell zu halten, verspreche aber nichts.

Zudem bin ich auch nicht dafür verantwortlich, wenn danach euer MacOS nicht mehr funktioniert oder „Lösungen-X-oder-Y“ sich plötzlich anders verhalten, als vorher. Bitte nur mit Köpfchen nachmachen :-)

Kommentare und Anregungen zum Text sind erwünscht, bitte an meine Mailadresse schicken.

Kleines Inhaltsverzeichnis:

  1. Die Installation und Einrichtung von ASP.NET vNext unter MacOS X Yosemite. Die Anleitung funktioniert IMHO auch mit älteren Versionen von MacOS, das probiere ich aber nicht aus und garantiere auch hier für nichts.
  2. Wir bauen uns ein Beispielprojekt und damit eine kleine Basisseite mit MVC6. Das alles machen wir noch ohne eine großartige Entwicklungsumgebung und ich versuche alles zu ausführlich, wie möglich zu zeigen.
  3. Ich richte mir „Sublime Text 3“ als Entwicklungsumgebung für ASP.NET vNext ein. Ein kurzer Überblick über den aktuellen Stand.
    So jetzt ist es genug Einleitung. Ich steigen gleich in die Entwicklung ein und damit, wie wir den Stoff auf unsere Kiste bekommen.

Installation

Es gibt ein paar Werkzeuge, die sollte jeder ernsthafte Benutzer von MacOS auf seinem Rechner haben. Dazu gehört auf jeden Fall Homebrew [^1]. Dieses Werkzeug verwende ich - auch sonst - relativ oft, um fehlene Software am Mac nachzuinstallieren und diese aktuell zu halten.

Die Mac-Entwickler von ASP.NET und DotNET sehen das sicher ähnlich, da eigentlich alle Pakete, die wir benötigen, darüber zu beziehen sind.

Mono

Die Basis von ASP.NET bleibt natürlich die DotNet-Runtime. Wer DotNET Anwendungen am Mac (oder Linux) schreiben möchte, der benötigt Mono[^2]. Mono ist eine DotNET-Implementierung für Linux und MacOS und liefert uns Bibliotheken und den Kompiler für unser Projekt. In der Tat gibt es Mono auch für Windows, allerdings sind da im Moment nur veraltete Pakete erhältlich.

Mono könnte man jetzt natürlich von Hand und aus dem Quelltext installieren… das dauert und macht (mir) jetzt nicht wirklich Spass. Viel schneller geht es mit Homebrew:

brew install mono

Je nach Paketversion bietet uns Homebrew ein Rezept zum Selberbrauen oder fertige Flaschen. Brauen bedeutet unterm Strich, dass es die Quellen herunterlädt, kompiliert und installiert. Fertige Flaschen, sind Binärpakete, die im Endeffekt einfach entpackt werden.

Installation Mono

In meinem Fall hier habe ich Glück und es steht noch eine fertige Flasche Mono 3.10.0 im Regal. Beim Installieren bitte aufpassen, ein älterer Jahrgang „Mono 3.4.0“ funktioniert nicht mit ASP.NET vNext.

ASP.NET vNext

ASP.NET[^3] ist mittlerweile genauso OpenSource, wie auch DotNET selbst. Neu an der aktuellen Entwicklung ist, dass die kommende DotNET-Runtime, zusammen mit dem geschriebenen Programm, in Form eines NuGet-Paketes ausgeliefert werden kann.

Eingepackt werden dann sogar nur die Teile von ASP.NET bzw. DotNET, welche zum späteren Zeitpunkt beim Ausführen auch benötigt werden. Dadurch wird nicht mehr ein komplettes DotNet-Framework geladen, sondern nur noch sehr kleine Häppchen.

Im Falle eines Sicherheitsupdates muss der Entwickler dann natürlich auch alle ausgerollten Programme aktualisieren, was wieder eine besondere Herausforderung darstellen kann und entsprechende Sorgfalt erfordert. Ich stelle mir aber vor, dass hier NuGet auch sehr hilfreich sein wird.

K Version Manager (KVM)

Das Erste, was mit der neuen Entwicklungsumgebung auf den Rechner schneit, ist der K Version Manager. Der KVM installiert uns verschiedene Versionen des „K Runtime Environment (KRE)“. Wobei mich im Moment natürlich nur der aktuelle Zweig interessiert.

Die Installation des KVM ist — natürlich — mit Homebrew möglich. Die dazu verwendeten Rezepte sind aber, bei Auslieferung von Homebres, noch nicht im Rezeptbuch vorhanden. Hab ich schonmal erwähnt, wie originell schräg ich Homebrew finde?

Also binde ich als erstes die fehlenden ASP.NET Rezepte[^4] mit an Homebrew an:

brew tap aspnet/k
ASP.NET vNext K Repository

Danach installieren ich den KVM:

brew install kvm

Die Installation sollte auch gleich automatisch die aktuelle Version von KRE installieren.

KVM Installation

Für den Fall, dass das Terminal das „kvm“-Kommando nicht kennt, setzt ein „source kvm.sh“ die benötigten Umgebungsvariablen. Ich habe den Befehl mit in meine „.profile“-Datei mit aufgenommen, dann muss ich das nicht jedes mal beim Öffnen der Shell tun.

Der KVM liegt übrigens im Verzeichnis „/Users/<benutzername>/.kvm“ und lässt sich daüber auch ganz gut wieder loswerden.

K Runtime Environment (KRE)

Die aktuelle Version der KRE wird über den KVM installiert. Ich möchte sicher gehen, dass auch die aktuelle Version installiert ist und aktualisiere mit:

kvm upgrade

Die gute Nachricht: Damit habe ich alle Werkzeuge am Rechner, um Webseiten mit ASP.NET vNext zu entwickeln. Interessanterweise fehlt an dieser Stelle hier das eigentliche ASP.NET vNext noch komplett, aber das kommt noch.

Installierte Umgebungen

KRE-Daten, landen im Verzeichnis /Users/<benutzername>/.kre. Auch wieder ganz praktisch, um alles loszuwerden und aufzuräumen.

Ein Beispielprojekt

Die Sache mit der Entwicklungsumgebung habe ich absichtlich erstmal zurück gestellt, damit ich mich auf das Beispielprojekt konzentrieren kann.
Mit diesem Projekt überprüfe ich auch gleich die Funktion der Installation.

Ich lege dafür einen neuen Ordner an, der meine Projekte enthalten wird. Das entspricht dem ehemaligen „Solution“-Ordner, der auch verschiedene Entwicklungsprojekte enthielt.

mkdir mysolution && cd mysolution

In diesem Ordner laden jetzt die ganzen Projekte. Für den Anfang ist das erstmal nur ein Projekt.

mkdir mvcproject && cd mvcproject

Zusammen mit einer neuen DotNet-Struktur hat Microsoft nach langer Zeit, es dürften so 10 Jahre gewesen sein, ein neues Format für die Projektdateien eingeführt. Alle Projektdaten landen jetzt in einer „project.json“-Datei.

Im Endeffekt orientiere ich mich hier an folgender Anleitung: http://www.asp.net/vnext/overview/aspnet-vnext/overview

Quelltext

Also gut. Für den ersten Schritt bauen ich jetzt Stück für Stück ein komplettes ASP.NET Projekt zu Fuß.
Die Zielprojektstruktur sieht dann folgend aus:

Projektstruktur

project.json

Wie schon geschrieben benötige ich eine Projektdatei mit dem Namen „project.json“, mit der das komplette Paket konfiguriert wird.

{
    "version" : "1.0.0-*",
        "authors": ["Christoph Jahn"],
        "description": "Ein schönes Beispielprojekt"
        "webroot" : "wwwroot",
        "exclude": "wwwroot/**/*.*",
        "dependencies": {
            "Kestrel": "1.0.0-alpha4",
            "Microsoft.AspNet.Diagnostics": "1.0.0-alpha4",
            "Microsoft.AspNet.Hosting": "1.0.0-alpha4",
            "Microsoft.AspNet.Mvc": "6.0.0-alpha4",
            "Microsoft.AspNet.Server.WebListener": "1.0.0-alpha4",
            "Microsoft.AspNet.StaticFiles": "1.0.0-alpha4"
        },
        "commands": {
            "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5001",
            "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004"
        },
        "frameworks": {
            "aspnet50": {},
            "aspnetcore50": {}
        }
}

Mehr Informationen über den Aufbau der Datei gibt es unter: https://github.com/aspnet/Home/wiki/Project.json-file

version / authors / description

Die Versionsnummer unserer Software. Wichtig, wenn ich später aus unserer Software ein NuGet-Paket baue, dass dann auf den Projektwebservern ausgerollt werden kann… Dazu gehören natürlich auch Authors bzw. Description.

webroot / exclude

Unter dem Verzeichnis, das in „webroot“ angegeben ist, landen alle statischen Dateien, wie „Stylesheets“, „Bilder“, usw. welche nicht kompiliert werden. Die Dateien hier werden einfach so ausgeliefert.

Dafür benötigen wir auch die Abhängigkeit „Microsoft.AspNet.StaticFiles“.

dependencies

Die Abhängigkeiten der Software von anderen Komponenten. Hier kommen die DotNET-Pakete und andere Bibliotheken rein, von denen die Webseite abhängt. Diese werden später, wenn die Seite ausgeführt wird, automatisch via NuGet heruntergeladen und auch beim Verteilen mit dazu gepackt.

commands

Die Einträge hier führt KRE als Befehl mit aus. „web“ oder „kestrel“ können also mit

k kestrel

gestartet werden. „kestrel“ ist für den MacOS-Entwickler besonders interessant, da dieser ein Cross-platform Webserver ist. Er funktioniert auch mit Linux. Damit wird die Seite also kompiliert und auch gleich ein Webserver gestartet, der sie hostet. „web“ ist die Variante für Windows.

frameworks

Die Laufzeitumgebung, für die das Projekt kompiliert wird. Das Projekt wird also für Desktop (aspnet50) oder Core CLR (aspnetcore50) gebaut.

Startup.cs

Die Datei, die als erstes ausgeführt wird. Als Konstruktor für die Funktion „Configure“ wird ein ApplicationBuilderobjekt übergeben, mir dem ich die Applikation zusammenbaue.

Ich verwende eine ausführliche Fehlerseite, bei Exceptions. Als kleine Anmerkung: Die funktioniert in der aktuellen Version nicht. Im VisualStudio 2014 CTP „4“ funktioniert es aber.

MVC füge ich ein und StaticFiles (wwwroot) möchte ich auch haben.

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;

namespace HelloMvc
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.UseErrorPage();
            app.UseServices(services => { services.AddMvc(); });
            app.UseMvc();
            app.UseStaticFiles();
        }
    }
}

„Controllers/HomeController.cs“

Ein einfacher Controller, der das Home-View zurückliefert. Keine Besonderheiten hier :-)

Im VS2014-CTP habe ich gesehen, dass kein Controller mehr benötigt wird, da alle Klassen, die auf „-Controller“ enden, als Controller verwendet werden.

using Microsoft.AspNet.Mvc;

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

„Views/Home/Index.cshtml“

Auch hier ein einfaches View, ohne Besonderheiten. Es gibt einfach nur eine Überschrift und ein bisschen Text aus.

@{
  var message = "Hello World";
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>Index Page</title>
</head>
<body>
  <h1>@message</h1>
  <p>Index page</p>
</body>
</html>

NuGet.config

Wenn wir die Webseite zum Start vorbereiten, dann werden die fehlenden Pakete aus dem Internet via NuGet nachgeladen. Dort sind als Standard allerdings die falschen URLs hinterlegt.

Mit der NuGet.Config korrigiere ich die Webpfade.

Diese Datei muss ein Verzeichnis über dem Projekt liegen.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="AspNetVNext" value="https://www.myget.org/F/aspnetmaster/api/v2" />
    <add key="NuGet.org" value="https://nuget.org/api/v2/" />
  </packageSources>
</configuration>

Webseite kompilieren und starten

Im Verzeichnis „mvcproject“ führe ich jetzt ein

kpm restore

aus. Der KPM liest jetzt die Projektdatei ein und lädt dann die ganzen fehlenden Pakete aus dem Internet nach.

kpm restore

Es gibt beim ersten Mal eine Menge Ausgaben.

Danach können wir den lokalen Webserver starten:

k kestrel

Wenn alles geklappt hat, dann erscheint auf der Kommandozeile einfach der Text: „Started“. Ist man fertig, dann beendet man den Server einfach mit einem Druck auf die ENTER-Taste.

Jetzt kann man per Browser unter der Adresse: http://localhost:5004 auf die Webseite zugreifen.

Meine MVC6 Seite

Webseite verteilen

Hier einfach mal ausprobieren: „kpm pack“ erzeugt im Unterverzeichnis „bin/output“ alles, das man braucht um die Webseite auf einen anderen Rechner zu bringen.

Kopiert das Verzeichnis auf einen Memorystick und für das Kommando „web.cmd“ mal auf einem Windowsrechner und führt es aus. Es gibt eine Abhängigkeit von der „klr“, die allerdings im Moment beim Packen noch nicht mitgeliefert wird.

kpm build“ baut einfach eine NuGet-Paket unseres Projektes.

„Sublime Text 3“ als Entwicklungsumgebung

Jeder hat einen Lieblingseditor in seiner Arbeitsumgebung. Ich liebe „Sublime Text 3“. Ich kann damit prima arbeiten und verwende ihn auch für einen Großteil meiner Webentwicklung.

Glücklicherweise bin ich nicht der Einzige, der dieser Ansicht ist und es gibt sogar für die .NET-Entwicklung zwei Sublimepakete, die uns die Arbeit am Mac erleichtern.

Kulture

Die Erweiterung Kulture[^5], ergänzt Sublime um die Unterstützung von vNext. Mit Cmd-Shift-P und im Suchfeld einfach mal ein K eingeben.

Das Menü wurde damit um ein „Run K Commands“ erweitert. Der Befehl liest die Projektdatei ein und bietet jetzt an, „k web“ bzw. „k kestrel“ gleich mit dem Editor auszuführen.

Dazu kommen die Kommandos „kpm restore“, „kpm pack“ und „kpm build“.

OmniSharp

Die fehlende Intellisenseunterstützung bekomme ich über das Paket: OmniSharp[^6].

Die Featureliste von OmniSharp ist lange: Auto Completion, Goto definition, Rename, Goto implementation, Syntax/Semantic error highlighting, Displays possible override methods, Find Usages, Format Document, …, Run Unit Tests, Build/ReBuild/Clean Solution, und viele mehr.

Auf jeden Fall sehr vielversprechend. Mit „Cmd-B“ kompiliert das Projekt.

OmniSharp Tools
OmniSharp Intellisense

Mehr Informationen zum Aktuellen Entwicklungsstand der Erweiterung gibt es unter:https://github.com/moonrabbit/OmniSharpSublime

Ausblick

Unterm Strich wird das ganz toll!

Yeoman

Im VisualStudio werden natürlich jede Menge Projektvorlagen mitgeliefert, bzw. sind herunterladbar.

Diese Lücke möchte „Yeoman“ schließen, es gibt einen Generator für ASP.NET. Den Generator gibt es unter https://github.com/ligershark/generator-aspnet

Mehr Informationen zu Yeoman liefert die zugehörige Webseite: http://yeoman.io

Installation und Verwendung in kurz

  • Installation: „npm install -g yo
  • Installation: „npm install -g generator-aspnet
  • Ausführen: „yo aspnet

Fußnoten

[^1]: Homebrew Webseite - http://brew.sh
[^2]: MonoMac - http://www.mono-project.com/docs/tools+libraries/libraries/monomac/
[^3]: ASP.NET - https://github.com/aspnet
[^4]: Weitere tolle Homebrew Repositories
[^5]: KultureSublime - https://sublime.wbond.net/packages/Kulture
[^6]: OmniSharp - https://sublime.wbond.net/packages/OmniSharp