Azure Logic Apps – ein Anwendungsszenario

Mit Azure Logic Apps lassen sich getriggerte Workflows erstellen und betreiben, deren einzelne Schritte von verschiedenen Web Services erledigt werden, die zu einem Geschäftsprozess orchestriert werden können. Azure Logic Apps können mit einem visuellen Designer im Azure Portal und einer JSON-basierten Definition Language entwickelt werden.

image

Azure Logic Apps, sind seit März 2015 offiziell verfügbar und seitdem im Preview-Status. Sie gehören zu den angebotenen Services des Azure App Service, zu dem auch API Apps, Web Apps und Mobile Apps gehören.

Die Idee zum Einsatz der Logic Apps entstand aus dem Konzept einer Art Microservices-Architektur. Die Aufgabenstellung: Konsolidiere Daten aus verschiedenen Backendsystemen und stelle sie für mobile Applikationen bereit. Leite Informationen aus mobilen Applikationen an zuständige Backendsysteme weiter. Daraus ergaben sich verschiedene Zuständigkeiten:

  • Schnittstellenadaption an verschiedene Backends sowie Transformation von Daten
  • Speichern konsolidierter Daten
  • Bereitstellung von Daten für Client-Anwendungen
  • Regelmäßige Datenaktualisierung
  • Ausführung von Operationen

 

Anwendungsszenario für Logic Apps

 Das Architekturkonzept stellt diese Zuständigkeiten in einen Zusammenhang, aus dem konkrete Dienste abgeleitet werden können.

clip_image002

Spezifische Adapter-Web Services stellen die Verbindung zu verschiedenen Backendsystemen (Backend A und B) her. Sie lesen und aktualisieren deren Daten und stellen diese zur Konsolidierung und Anzeige in einer Client-Anwendung bereit.

Die Client-Anwendung bezieht die konsolidierten Daten von einem zentralen Anwendungs-Web Service.

In der Mitte sitzen zwei Workflows für Datenaktualisierung und die Ausführung von backendspezifischen Aktionen. Sie sind als Azure Logic Apps implementiert. Die beiden Workflows tun nichts weiter, als Requests an Web Services zu senden und auf deren Responses zu reagieren. OK, sie benötigen einen Zeitplan und müssen gewisse Bedingungen auswerten, aber viel mehr Logik haben sie nicht. Jetzt könnte man diese Workflows mit .NET-Mitteln selbst implementieren, Logic Apps bieten die benötigten Funktionen aber bereits an und sind prädestiniert für die Erstellung von Workflows. Das benötigte Verhalten lässt sich rein deklarativ erstellen.

Das folgende Bild stellt das oben abgebildete Konzept mit den entsprechenden Azure Services dar, die für die Umsetzung geeignet sind (Empfehlung):

clip_image003

Was sind nun die wesentlichen Schritte, um eine derartige Architektur mit Hilfe von Logic Apps auf die Beine zu stellen? Vorausgesetzt es steht eine Azure Subscription zur Verfügung, lautet ein mögliches Vorgehen:

  1. Entwicklung der einzelnen Web Services (API Apps) und Deployment in die Azure Subscription
  2. Anlegen der Logic Apps und Einbindung der zuvor erstellten API Apps

Eigentlich einfach. Wenn denn alles, wie in den einschlägigen Tutorials erklärt, funktioniert.

Immer noch Preview

Aufgrund des Preview-Status der Technologie unterliegen Logic Apps immer noch einer hohen Änderungshäufigkeit. Schnittstellen ändern sich, einmal deployte API Apps stehen auf einmal nicht mehr im Logic App Designer zur Auswahl, und ähnliche “Überraschungen” warten auf den interessierten Entwickler. Ob man Logic Apps bereits in kritischen Projekten einsetzen will, sollte daher gut überlegt sein. Die allgemeine Verfügbarkeit der Logic Apps, d. h. das Verlassen des Preview-Status wird von Microsoft für Q2 2016 angekündigt.

Wie schon erwähnt, können Logic Apps mit einem visuellen Designer “zusammengeklickt” werden. Der Designer hat jedoch noch Grenzen, und es sind noch nicht alle Features vom Designer unterstützt.. Sämtliche Möglichkeiten hingegen stehen dem Entwickler offen, wenn er sich vorab intensiv mit der Logic App Definition Language auseinandersetzt. Ist ein Workflow damit einmal entwickelt, unterstützt der Designer wieder bei der Visualisierung desselben. Auch Änderungen lassen sich im Designer durchführen, aber eben nur in gewissen Grenzen. Daher lautet die Empfehlung, einen Workflow zunächst rudimentär im Designer aufzusetzen, so dass die wesentlichen Services (Schritte) enthalten sind, und danach im Code weiterzuarbeiten. Zur Kontrolle kann schlussendlich der Workflow wieder im Designer geöffnet und verifiziert werden.

Visual Studio unterstützt bei der Entwicklung von Logic Apps. Mit dem Azure SDK kommen Projekt-Templates und Publishing-Mechanismen ins Studio.

Noch ein Wort zu den API Apps. Azure unterscheidet mittlerweile zwischen Managed APIs und Custom APIs. Die eigenen entwickelten Web Services fallen unter die Custom APIs. Aus .NET-Entwicklersicht handelt es sich um gewöhnliche Web APIs, die jedoch zusätzlich ihre Schnittstelle als Swagger-Definition exportieren. Mit Hilfe dieser Swagger-Definition können entsprechende Clients generiert werden. Azure nutzt dies z. B. für die Generierung eines entsprechenden UI für die Parameterdefinition im Logic App Designer. Erstellt man im Visual Studio eine neue API App, so wird automatisch eine Swagger-Definition durch das Projekt-Template hinzugefügt (NuGet).

Zur weiteren Lektüre und zum vertiefenden Einstieg in die Materie seien die relativ gut dokumentierenden Blog-Artikel auf der Azure Website empfohlen.

Azure AD B2C – externe Benutzer verwalten

Microsoft bietet mit dem Azure Active Directory (Azure AD) seit geraumer Zeit einen Benutzerverwaltungsdienst für Unternehmen in der Cloud an. Allerdings ist dieser für die Verwaltung von Benutzern einer Website nicht gut geeignet, da eine Self-Service Registrierungsmöglichkeit fehlt. Benutzer werden stattdessen durch einen Administrator verwaltet. Neue Benutzer können sich nicht selbst einen Account anlegen. Braucht man diese Möglichkeit für eine Website, war man bisher auf Drittlösungen oder eine Eigenentwicklung angewiesen. Man konnte z. B. den Thinctecture IdentityServer einsetzen, ein OpenSource-Projekt zur Implementierung von Identitätsdiensten. Seit September 2015 gibt es auch einen Azure-Dienst für diesen Zweck – Azure AD B2C; aktuell noch als Public Preview.

Azure AD B2C bringt im Vergleich zum „klassischen“ Azure AD die Möglichkeit mit, dass sich Benutzer selbst registrieren können. Und somit wird das Ganze für Consumer Web-Anwendungen nutzbar. Der Aufwand für die Entwicklung einer Benutzerverwaltung entfällt.

Azure AD B2C ist als Azure Service hochverfügbar und global erreichbar ausgelegt. Es bietet eine leicht verständliche Benutzeroberfläche zur Benutzerverwaltung und für die Konfiguration der Authentifizierungsaspekte. Der Entwickler, der den Dienst für seine Anwendung nutzen möchte, braucht diesen nur mit etwas Konfiguration und wenigen Zeilen Code in seine Applikation zu integrieren.

Voraussetzung ist wie immer, dass eine Azure Subscription zur Verfügung steht. Wichtig zu wissen ist, dass ein bestehendes Azure AD nicht um die B2C-Option erweitert werden kann. Genauso wenig kann ein einmal erstelltes Azure AD B2C in ein konventionelles Azure AD umgewandelt werden. Die Wahl der B2C-Option steht ausschließlich bei der Anlage des Verzeichnisses zur Verfügung. Es herrscht offensichtlich eine starke Trennung zwischen Unternehmens- und B2C-Verzeichnissen.

Alsdann lässt sich in vier wesentlichen Schritten die Integration des Azure AD B2C in die eigene Anwendung vollziehen:

  1. Anlegen des Verzeichnisses als Azure AD B2C
  2. Registrieren der Anwendung im Azure AD B2C
  3. Festlegen von Policies für Registrierung, Anmeldung, Profilverwaltung und Passwort-Reset
  4. Integration in den Code und die Konfiguration der Anwendung

Azure AD B2C Verzeichnis anlegen

Die Benutzeroberfläche für Anlage und Management des Azure AD B2C teilt sich noch auf die beiden Azure-Portale (klassisch und neu) auf. So legt man zunächst im klassischen Azure-Portal ein neues Active Directory-Verzeichnis an und wählt dabei die B2C-Option:

Azure AD B2C anlegen

Danach erhält man in der Konfigurationsansicht des neu angelegten Verzeichnisses einen Link zu den B2C-Einstellungen, der ins neue Azure-Portal führt:

image

Man befindet sich dort nun direkt im neu angelegten Azure AD des B2C-Mandanten, wie man an den Daten des angemeldeten Benutzers oben rechts erkennen kann. Das neue Verzeichnis befindet sich auch in der Liste aller anderen Verzeichnisse, auf die man mit dem angemeldeten Benutzer Zugriff hat. Somit ist es leicht, zwischen allen Verzeichnissen zu wechseln, und das nicht nur zwischen den Unternehmensverzeichnissen.

Anwendung registrieren

Sofern man direkt vom klassischen Azure-Portal gekommen ist, werden die Azure AD B2C Einstellungen direkt geöffnet. Anderenfalls kann man diese Einstellungen über den Link “Azure AD B2C” unter “Durchsuchen” öffnen. Die Registrierung der Anwendung nimmt man im Bereich “Applications” vor:

Anwendung mit Azure AD B2C verbinden

Schließt die Anwendung eine serverseitige Komponente ein, stellt man “Include web app / web API” auf “Yes” und legt mindestens eine Redirect URI fest. Das ist die URI, an die Azure AD B2C nach erfolgreicher Benutzerauthentifizierung das Benutzer-Token sendet. Azure AD B2C leitet den Browser des Benutzers nach erfolgreicher Authentifizierung zu dieser URI um.

Zur Erhöhung der Sicherheit empfiehlt es sich, einen Key zu generieren, der bei der Nutzung der serverseitigen Komponente mitgegeben werden muss.

Schließt die Anwendung einen nativen Client ein, z. B. eine mobile App, ist “Include native client” auf “Yes” zu stellen.

Nachdem man das Anlegen der Anwendung im Azure AD B2C mit “Create” abgeschlossen hat, findet man in den Details der erstellten Anwendung deren Application Client ID:

image

Die Application Client ID und den zuvor generierten Key braucht man später im Code bzw. der Konfiguration der eigenen entwickelten App, die Azure AD B2C benutzen soll.

Eine aktuelle Einschränkung des Azure AD B2C erfordert für alle Anwendungsbestandteile dieselbe Application Client ID. Das bedeutet, dass Client- und Serverseite der Anwendung aus Sicht des Azure AD B2C eine Einheit bilden. Es ist also nicht möglich, andere Apps mit derselben Serverseite kommunizieren zu lassen, z. B. 2 Apps teilen sich einen Web Service.

Policies festlegen

Mittels Policies wird definiert, was ein Benutzer tun kann und auf welche Art und Weise. Soll sich ein Benutzer selbst registrieren können, braucht es mindestens eine Sign-up Policy. Für die Anmeldung des Benutzers braucht es mindestens eine Sign-in Policy. Soll der Benutzer sein Profil selbst verwalten können, z. B. für die Änderung der E-Mail-Adresse, braucht es mindestens eine Profile Editing Policy. Das gilt analog für das Zurücksetzen des Benutzerpassworts. Ist ein Policy-Typ nicht angelegt, steht die korrespondierende Funktionalität dem Benutzer nicht zur Verfügung.

Eine Policy kann man sich als Container für einen Satz von Einstellungen vorstellen, der für die korrespondierende Funktionalität gelten soll.

Dazu gehören Identity Providers, z. B. Google oder Facebook. Man kann also seinen Benutzern erlauben, sich mit ihren Social Network Accounts zu registrieren und sich mit diesen anzumelden. Vorteil für den Benutzer ist, dass er sich keine weiteren Zugangsdaten merken muss.

Weiterhin kann man in einer Policy definieren, welche Benutzerattribute bei der Registrierung abgefragt werden sollen oder welche der Benutzer im Rahmen seiner Profilverwaltung bearbeiten kann, z. B. Adressinformationen oder Namen. Die Benutzerinformationen, die an eine Anwendung aus dem Azure AD B2C zurückgegeben werden sollen, so genannte Claims, definiert man ebenfalls innerhalb einer Policy.

Des Weiteren wird die Gültigkeitsdauer von Authentifizierungen, also der Benutzer-Tokens, in einer Policy festgelegt. Oder auch die Ablaufdauer von Benutzer-Sessions. Aus Sicherheitsgründen auch interessant ist die Möglichkeit, Multi-Factor Authentication zu nutzen, d. h. der Benutzer muss sich zusätzlich zu Benutzername und Passwort mit einem Code authentifizieren, der ihm per SMS oder Anruf mitgeteilt wird.

Damit die Web-Formulare, die der Benutzer zu sehen bekommt, dem Look and Feel der Anwendung entsprechen, lassen sich diese ebenfalls innerhalb der Policy definieren. Dabei kann man sogar die URI festlegen, die auf die Custom Page zeigt. Details zum Customizing dieser Web-Formulare kann man in dem Artikel über Azure AD B2C UI Customization nachlesen.

Welche Policy zum Einsatz kommt, bestimmt die Anwendung, die je nach Geschäftslogik bei den jeweiligen Requests an das Azure AD B2C den Namen der gewünschten Policy mitgibt.

Code und Konfiguration der Anwendung

Was bleibt, ist die eigene Anwendung für die Nutzung des Azure AD B2C anzupassen.

Die Kommunikation mit dem Azure AD B2C geschieht mittels gesicherter HTTP Requests. Für serverseitige .NET-Applikationen, wie Web Apps und Web APIs, unterstützt hierbei Microsofts OWIN-Bibliothek, die über NuGet in die eigene Anwendung eingebunden werden kann. Wie das im Detail geht, kann man im Artikel “Build a .NET web app” nachlesen.

Für Single Page Applications (JavaScript) habe ich noch keine entsprechenden Libraries gefunden.

Für Xamarin.Forms Applikationen existiert seit kurzem ein GitHub-Projekt mit einer Beispielanwendung, die sicher einen Blick wert ist.

Die Unterstützung weiterer Plattformen wie natives Android und natives iOS sowie NodeJS gibt es von Microsoft Schnellstartanleitungen.

Zur Automatisierung der Benutzerverwaltung lässt sich die Azure AD Graph API verwenden. Über eine Web Service Schnittstelle lassen sich so Benutzer anlegen, bearbeiten und löschen.

Kosten

Azure AD B2C ist noch im Preview-Status und kostenlos verfügbar. Das Preismodell, welches nach Verlassen des Preview-Status gilt, kann man aber schon nachlesen. Die beiden monatlichen Größen, nach denen abgerechnet werden wird, sind Anzahl der Nutzer, die im Verzeichnis gespeichert werden, sowie die Anzahl an Authentifizierungen oder Token-Aktualisierungen, die im Azure AD B2C durchgeführt werden.

Die ersten 50.000 Benutzer sind kostenlos. Darüber hinaus zahlt man pro Benutzer zwischen 0,00093 und 0,00067 EUR, je nach Menge. Ähnlich sieht es bei den Authentifizierungen aus. Hier sind ebenfalls die ersten 50.000 im Monat frei. Danach kosten sie 0,00236 bis 0,00118 EUR pro Authentifizierung. Multi-Factor Authentication kostet pauschal oben drauf 0,0253 EUR pro Authentifizierung. Für Microsoft Enterprise Agreements können besondere Preise erfragt werden.

Berechnungsbeispiel für 100.000 Benutzer, die sich täglich anmelden:

  • (100.000 – 50.000) x 0,00093 EUR = 46,50 EUR für die verwalteten Benutzer
  • (100.000 – 50.000) x 0,00236 EUR x 31 Tage = 3.658,- EUR für die Authentifizierungen

Für dieses Szenario ergäben sich also 3.704,50 EUR an monatlichen Kosten.

Fazit

Microsoft Azure AD B2C kostet Geld, erspart jedoch eine Menge Arbeit und macht die Verwaltung von sensiblen Benutzerdaten sicherer, als man es selbst umsetzen könnte. Es ist global und hochverfügbar. Durch die Einbindung von Social Network Identity Providern wird dem Benutzer die Anlage eines weiteren Accounts im Internet erspart. Die Gefahr, die von der Verwendung immer gleicher Passwörter – aus Bequemlichkeit – auf verschiedenen Websites ausgeht, ist dadurch gebannt. Die Benutzerdaten an sich werden nicht in der eigenen Anwendung gespeichert, und so ist die eigene Anwendung kein weiteres Ziel für Angreifer. Diese interessieren sich meist nicht für die Daten der eigenen Anwendung, sondern viel mehr für die Benutzeridentitäten. Wenn die nicht in meiner eigenen Anwendung liegen, kann ich besser schlafen.

Azure App Hosting kurz erklärt

Microsoft Azure bietet für Entwickler eine große Menge an Services und Features. Hier den Überblick zu behalten ist nicht leicht. Steht man vor der Frage, mit seiner Anwendung in die Cloud zu gehen oder die Anwendung auf den Betrieb in der Cloud auszurichten, und zwar von Anfang an, ist es wichtig, die wesentlichen Varianten des Azure App Hosting für die eigene Anwendung in der Cloud zu kennen. Das vermeidet spätere Frustration, falls man “auf das falsche Pferd” gesetzt hat.

Die zentrale Frage ist also, wo und wie hoste ich meine Anwendung? Habe ich mich für ein Cloud-Hosting entschieden, stehe ich vor der Wahl zwischen drei wesentlichen, verschiedenen Modellen:

Die drei unterscheiden sich hauptsächlich im Hinblick auf die Einflussmöglichkeiten, die man bzgl. Konfiguration und Betrieb hat.

App Service

App Service ist das jüngste Kind des Azure App Hosting und ist als waschechte Platform as a Service (PaaS) einzuordnen. An die darunterliegende Systemsoftware kommt man nicht heran. Das Patch Management und die Wartung der Runtime-Versionen übernimmt Azure.

Mit App Service kann man im Wesentlichen zwei Arten von Azure Apps hosten: Web Apps und Mobile Apps. Früher bezeichnete Microsoft diese übrigens als Web Sites und Mobile Services. Unter Web Apps fallen alle Arten von Webanwendungen, z. B. Web Sites und Web Services. Die Mobile Apps fassen diverse Services für die Entwicklung und Unterstützung von mobilen Anwendungen zusammen, z. B. Notification Services und Backend Web Services sowie die Generierung von Client App Code für die unterschiedlichen mobilen Betriebssysteme, z. B. für iOS.

App Services skalieren automatisch, d. h. man kann festlegen, dass bei Erreichen bestimmter Lastschwellen zusätzliche Instanzen der Anwendung aktiviert werden. Somit stehen zu jeder Zeit entsprechend den Leistungsanforderungen genügend Ressourcen zur Verfügung.

Für die Sicherheit sorgt zum einen App Service selbst, indem die eigene App Service-Instanz isoliert vom Internet und von Azure-Ressourcen anderer Nutzer betrieben wird. Der Austausch von Applikations-Secrets erfolgt zwischen der App Service-Anwendung und anderen Azure-Ressourcen immer verschlüsselt, und die Kommunikation erfolgt ausschließlich innerhalb von Azure. Kommunikation mit externen Ressourcen erfolgt ebenfalls verschlüsselt. Mit einem 24-Stunden-Threat Management sorgt Azure dafür, dass entsprechende Attacken erkannt und abgewehrt werden.

Zum anderen muss der Entwickler dafür Sorge tragen, dass seine Anwendung auf Applikationsebene zeitgemäß geschützt ist, z. B. gegen SQL Injection, Cross Site Scripting usw. Für die Benutzerauthentifizierung und -autorisierung bietet App Service eingebaute Mechanismen an, die es z. B. erlauben, den Zugriff auf seine Anwendung mit OAuth 2.0 zu sichern. So kann beispielsweise Azure Active Directory für die Benutzerverwaltung verwendet werden. Auch externe Identitätsprovider wie Google, Facebook und Twitter können zur Benutzeridentifizierung eingebunden werden.

Cloud Services

Cloud Services, obwohl schon etwas älter, haben nach wie vor ihren Charme als interessante Azure App Hosting-Alternative, gerade wenn man mehr Einfluss auf die Konfiguration der Hosting-Umgebung nehmen muss. Cloud Services sind virtuelle Windows-Maschinen. Man kann sich mit ihnen per Remotedesktop verbinden und damit Einfluss auf die Konfiguration der Betriebsumgebung nehmen. Zum Beispiel können eigene Dienste oder geplante Jobs eingerichtet werden. An Betriebssystemen stehen zur Wahl:

  • Windows Server 2008 SP2
  • Windows Server 2008 R2
  • Windows Server 2012
  • Windows Server 2012 R2

Cloud Services unterteilen sich in zwei Rollen von virtuellen Maschinen: die Worker Role und die Web Role. Der Unterschied zwischen beiden besteht darin, dass die Web Role zusätzlich Internet Information Services (IIS) installiert hat, und somit als Web Server fungieren kann. Die Worker Role hingegen ist für Hintergrunddienste/-aktivitäten konzipiert, z. B. für aufwändige Berechnungen u. ä. Die Idee ist, dass eine Web Role derartige Berechnungen an eine Worker Role delegieren kann. Die Kommunikation zwischen beiden kann beispielsweise über eine Message Queue erfolgen.

Auch Cloud Services lassen sich automatisch skalieren, je nach Leistungsanforderung, nach oben und unten. Automatische Skalierung hat Vorteile in zweierlei Hinsicht. Es können damit jederzeit genügend Ressourcen bereitgestellt werden, um die Nutzungsanforderungen abzudecken. Da die Kosten für die Nutzung von Azure Services mit der Anzahl von Instanzen und deren Ausprägung steigen (und fallen), sorgt die automatische Skalierung für einen jederzeit effizienten Einsatz der benötigten Services.

Welche Art von Services sind Cloud Services nun eigentlich, Platform oder Infrastructure as a Service (Iaas)? Betrachtet man die Verwaltbarkeit über Remotedesktop, fühlt sich dies nicht wesentlich anders an als bei Azure Virtual Machines. Nur, dass man es ausschließlich mit Windows-Maschinen zu tun hat. Linux bleibt hier außen vor. Das legt den Schluss nahe, man hätte es mit IaaS zu tun. Hat man sich dann mal verbunden und wirft einen Blick in die Windows Update-Einstellungen, stellt man fest, dass diese “von einem Administrator” gemanagt werden. Das und die Möglichkeiten der automatischen Skalierung, also das Hinzufügen weiterer und größerer Instanzen (VMs) je nach Leistungsanforderungen, deutet jedoch mehr auf PaaS hin. Die Wahrheit liegt wohl, wie so oft, dazwischen, und die Cloud Services lassen sich weder ausschließlich in die eine noch in die andere Kategorie einordnen.

Virtual Machines

IaaS in Reinform stellen Azure Virtual Machines dar. Auf ihnen kann man im Prinzip alles installieren, was man für sein Azure App Hosting braucht und was Windows oder Linux als Betriebssystem voraussetzt. Für die Bereitstellung der VMs inkl. Auswahl benötigter Systemsoftware und das Patch Management muss man somit selbst sorgen. Es stehen immer nur so viele Maschinen bereit, wie man selbst konfiguriert hat. Automatische Skalierungsmöglichkeiten bestehen out-of-the-box nicht. Man muss sie bei Bedarf selbst implementieren. Auch für Load Balancing, Hochverfügbarkeit und Security ist selbst zu sorgen. Also alles so, als verwalte man Maschinen im eigenen Rechenzentrum. Dafür hat man bei der Konfiguration der Maschinen weitgehend freie Hand bis hin zur Auswahl des Betriebssystems (Windows, Linux). Azure bietet zudem eine ganze Reihe von vorkonfigurierten Systemimages, die aus einer Gallery ausgewählt werden können, um eine eigene virtuelle Maschine aufzusetzen.

Vergleich der Azure App Hosting-Varianten

Das sind sie, die drei wesentlichen Azure App Hosting-Varianten für die eigenen Anwendungen. Für welche soll man sich nun aber entscheiden? Die folgende Abbildung stellt noch einmal die 3 Varianten gegenüber.

Azure App Hosting - Varianten im Vergleich

Quelle: https://azure.microsoft.com/en-us/documentation/articles/choose-web-site-cloud-service-vm/

Wenn es um die Neuentwicklung von Anwendungen geht, ist der App Service für die meisten Webapplikationen die beste Wahl. Er deckt alle Anforderungen an den professionellen Betrieb von Webanwendungen ab. Es gibt die automatische Skalierung, Hochverfügbarkeit inkl. Geo-Redundanz, Load Balancing sowie die so genannten WebJobs für Hintergrundaktivitäten, z. B. für die Erzeugung von Thumbnails aus hochgeladenen Bildern.

Steht man vor der Aufgabe, ein bestehendes Anwendungssystem in die Cloud zu migrieren, und hat das System spezielle Anforderungen an die Betriebsumgebung, stößt man an die Grenzen des App Service. Man kann dann auf die Cloud Services ausweichen, sofern das Anwendungssystem auf Windows-Maschinen lauffähig ist. Anderenfalls, oder wenn die Migration sehr schnell und einfach gehen soll ohne großartige Änderungen an der Anwendung, sind selbstverwaltete Virtual Machines die geeignetere Alternative. Allerdings ist dann für die Wartung komplett selbst zu sorgen.

Fazit

Braucht man für die Migration bestehender Anwendungen größtmögliche Flexibilität und möchte so nah wie möglich an seinem bisherigen Szenario bleiben, macht man mit Virtual Machines erst mal nichts verkehrt. Für Neuentwicklungen sollte man aber auf die App Services setzen, um größtmögliche Vorteile aus dem Azure Cloud Hosting zu ziehen und sich auf das Wesentliche, die Entwicklung der Anwendung, zu konzentrieren. Man kann ganz klein, also mit wenigen Ressourcen und zum Teil sogar kostenlos beginnen und später bequem skalieren, wenn die Leistungsanforderungen steigen. Will man das Beste aus beiden Welten, sind Cloud Services interessant.

Continuous Integration mit Visual Studio Online und Microsoft Azure

Zur professionellen Software-Entwicklung gehört die Einrichtung eines automatischen Build-, Test- und Deployment-Systems. Microsoft stellt mit seinem neuen Build-System ein auf den ersten Blick leicht zu bedienendes Werkzeug zur Verfügung. Setzt man es praktisch ein, stößt man jedoch schnell an die Grenzen von Intuition und Dokumentation. Dieser Artikel zeigt exemplarisch an einem realen Projekt die Einrichtung eines kompletten Continuous Integration-Prozesses (CI) und schildert die gewonnenen Erfahrungen.

Im vorliegenden Projekt wird der Code in Visual Studio Online (VSO) gehostet und die Anwendung auf Microsoft Azure deployt. Die Anwendung besteht im Wesentlichen aus einem Web Service (Web API), der in Azure als API App deployt wird.

Während man früher mit MSBuild- und PowerShell-Skripten hantieren musste, um ein leistungsfähiges CI-System aufzubauen, bringt das neue Build-System ein Web User Interface mit, mit dem sich die verschiedenen Prozessschritte visuell zusammenbauen lassen. Ein fertiger Prozess stellt sich dann so dar:

BuildDefinition

Wie baut man nun das Ganze auf? Zunächst einmal sind Voraussetzungen zu erfüllen.

Vorbereitung

So benötigt man mindestens einen Build Agent, der den Code baut. Ist der gesamte Code in VSO gehostet, kann man auf einen Hosted Pool von Build Agents zurückgreifen, muss also keinen eigenen Build Agent bereitstellen. Dabei gelten zwar ein paar Einschränkungen, die aber für das vorliegende Beispielprojekt nicht von Bedeutung waren. Unter dem obigen Link findet man unter anderem die Liste der Software, die auf einem Hosted Build Agent installiert ist. Braucht man mehr, muss man einen eigenen Build Agent aufsetzen (on-premise).

Um den Hosted Pool anzusprechen, ist beim Ausführen eines Build nur eine Option zu setzen. Ich komme darauf später zurück (siehe Globale Parameter).

Um auf Microsoft Azure deployen zu können, muss das Build-System Kenntnis von der entsprechenden Azure Subscription haben, auf die deployt werden soll. Das erreicht man mit folgenden Schritten:

  1. Öffnen der Projektseite im VSO, z. B. https://{VSO Account}.visualstudio.com/DefaultCollection/{Team Project}
  2. Navigieren in die Account Administration (kleines Zahnrad oben rechts)
  3. Wechseln auf den Tab Services

Hier kann man über New Service Endpoint > Azure eine Azure Subscription hinzufügen:

DeploymentServiceEndpoint

Wie dieser Dialog auszufüllen ist, kann man unter “Register your Azure subscription” nachlesen.

Somit steht die Subscription für die Erstellung einer Build-Definition und folglich als Deployment-Ziel zur Verfügung.

Der Build-Prozess

Jetzt geht es an das Aufbauen des Build-Prozesses, welcher die folgenden Schritte enthalten wird:

  1. PowerShell: Ausführen eines PowerShell-Skripts, um pre-build-Aktionen durchzuführen (hier ein Backup der aktuellen OData-Metadaten)
  2. Visual Studio Build: Bauen der Solution
  3. Visual Studio Test: Ausführen der Unit Tests
  4. Publish Build Artifacts: Kopieren des Build Output vom Build Agent in einen Drop Folder im VSO
  5. Azure Web App Deployment: Deployment der Applikation als Microsoft Azure API App

Doch zunächst die allgemeine Konfiguration des Build.

Globale Parameter

Repository Tab: Hier stellt man das Source Code Repository ein, aus dem die zu bauenden Sourcen heruntergeladen werden sollen.

Repository

Der Repository Name entspricht im Falle von Team Foundation Version Control dem Namen des Team Project.

Unter Mappings wird festgelegt, welche Repository-Ordner beim Herunterladen des Codes eingeschlossen (Map) und welche ausgeschlossen (Cloak) werden. Meistens wird man als Map den Solution-Ordner einstellen. Es werden damit zu Beginn des Build-Prozesses alle Dateien und Ordner unterhalb des “geMapten” Ordners heruntergeladen, außer den als Cloak definierten Ordnern.

Variables Tab: Hier kann man Variablen vordefinieren und an allen Stellen innerhalb der verschiedenen Build Steps wiederverwenden. Pro Variable kann auch festgelegt werden, ob diese für einen einzelnen Build-Lauf überschrieben werden kann (Allow at queue time).

Variables

Die hier verwendeten Variablen haben folgende Bedeutungen:

  • BuildConfiguration entspricht der im Visual Studio verwendeten Build-Konfiguration, also im Regelfall Release. Etwaige Compiler Conditions oder auch web.config-Transformationen beziehen sich auf diese Einstellung.
  • BuildPlatform entspricht der im Visual Studio verwendeten Build Platform.
  • WebAppName ist der Name der Azure App (hier API App). Achtung, das ist nicht der Anzeige-Name der API App, sondern der Name des API App Host, wie in der folgenden Abbildung zu sehen.

WebAppName

Triggers Tab: Hier kann eingestellt werden, wann und unter welcher Bedingung der Build automatisch ausgeführt wird. Im vorliegenden Fall wird der Build immer dann ausgeführt, wenn in den angegebenen Respository-Pfad (Filters) etwas eingecheckt wurde. Die Option Batch changes besagt, dass nicht bei jedem einzelnen Check-in ein Build gestartet wird, sondern nur dann, wenn nicht schon ein Build derselben Definition läuft. Dann fließt also nicht genau ein Check-in in den Build ein, sondern alle Check-ins, die noch nicht Teil des vorangegangenen Builds waren (Batch).

Triggers

General Tab: Das wichtigste hier ist die Default queue. Möchte man auf den Build Agent Pool zurückgreifen und hat keinen eigenen Build Agent aufgesetzt, wählt man hier Hosted. Der Wert ist ein Default-Wert und kann beim manuellen Starten eines Build übersteuert werden.

Damit haben wir die generellen Einstellungen für die Build-Definition und können mit der Konfiguration der einzelnen Build Steps fortfahren.

Build Steps

PowerShell

Möchte man im Verlaufe des Build-Prozesses ein allgemeines PowerShell Script ausführen, kann man diesen Build Step einbauen.

PowerShell

Der Script filename ist der Pfad des PowerShell Script im Source Code Repository.

Die Arguments entsprechen den Parametern, die das Script erwartet.

Die Control Options bieten noch die Möglichkeiten, einen Build Step zu disablen, den Build-Prozess nicht zu stoppen, falls dieser Step auf einen Fehler läuft (Continue on Error) oder einen Build Step immer auszuführen, d. h. auch dann, wenn die vorhergehenden Steps auf Fehler liefen (Always Run). Diese Optionen können für jeden Build Step-Typen eingestellt werden.

Visual Studio Build

Dies ist der eigentliche Build Step, der den Source Code kompiliert und den Build Output erzeugt.

VisualStudioBuild

Die Solution ist der Pfad im Source Code Repository zu dem Solution File, das gebaut werden soll.

Die Configuration ist die Build-Konfiguration. Im Beispiel ist die Verwendung der entsprechenden Variable zu sehen, wie sie im Variables Tab definiert ist.

Visual Studio Test

Dieser Step führt sämtliche Unit Tests durch.

VisualStudioTest

Test Assembly enthält eine Pfad-Definition mit Wildcards, um die auszuführenden Test Assemblies zu definieren. Im vorliegenden Fall werden in allen Ordnern mit Namen der Build-Konfiguration die Assemblies mit “test” im Namen hergenommen, wobei alle in den Ordnern “obj” ausgeschlossen werden sollen. Der Pfad ist relativ zum Solution-Ordner zu sehen.

Publish Build Artifacts

Dieser Step transportiert den Build Output vom Build Agent in einen Ordner im Visual Studio Online. Somit werden die Build-Ergebnisse aufgehoben und stehen so lange zur Verfügung, wie der Build Record an sich zur Verfügung steht (siehe auch Retention Tab in der Build-Definition).

PublishArtifacts

Der Copy Root setzt sich wie folgt zusammen:
$(Agent.BuildDirectory)/{Repository-Name}/{Projektordner}, wobei {Projektordner} der Ordner des gebauten Web App-Projekts ist.

Artifact Name ist der Name des Drop Folder, in den die Build Outputs kopiert werden sollen. Wichtig: Aus dem Drop Folder werden die Dateien für das Deployment auf Azure genommen (folgender Build Step).

Der Drop Folder ist, nachdem der Build mal gelaufen ist, in den Build-Ergebnissen im Artifacts Tab abrufbar:

DropFolder

Bleibt noch das eigentliche Deployment der App nach Microsoft Azure.

Azure Web App Deployment

In diesem Schritt wird die Anwendung in Azure als API App bereitgestellt.

WebAppDeployment

Als Azure Subscription ist die Subscription zu wählen, in die deployt werden soll. Hier stehen die Subscriptions zur Auswahl, die bei der Vorbereitung (s. o.) dem Team Project zugeordnet worden sind.

Der Web App Name entspricht dem Namen des API App Host (s. o.) und wird als Variable referenziert.

Die Web App Location entspricht der Location der API App, wie sie in Azure angelegt ist:

Location

Das Web Deploy Package verdient besonderes Augenmerk. Es ist der Pfad auf das zu deployende Web App Package. Der Pfad setzt sich hier wie folgt zusammen:
$(Agent.BuildDirectory)/artifacts/{Artifact Name}/obj/$(BuildConfiguration)/Package/{Projektname}.zip
Nun wird dieses ZIP File nicht standardmäßig erzeugt. Dafür braucht es etwas Handarbeit in der Projektdatei (.csproj). Hier sind 4 Konfigurationseinträge einzufügen innerhalb der Property Group für die Release Build-Konfiguration.

<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props')" />
...
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<FilesToIncludeForPublish>OnlyFilesToRunTheApp</FilesToIncludeForPublish>
<DeployOnBuild>true</DeployOnBuild>
<DeployTarget>Package</DeployTarget>
<PackageAsSingleFile>true</PackageAsSingleFile>
</PropertyGroup>
...
</Project>

Damit wird für das Web App-Projekt beim Release Build ein Package erzeugt und im Ordner {Projektordner}objReleasePackage mit dem Namen {Projektname}.zip abgelegt. Dieses Package wird beim Azure Deployment hochgeladen.

Nachdem also schlussendlich die modifizierte Projektdatei im Source Code Repository aktualisiert wurde, kann der Build Prozess ausgeführt werden.

Versionierung

Build-Definitionen werden automatisch durch das Build-System versioniert. Bei jedem Speichern der Definition wird nach einem Kommentar für die Änderungen gefragt. Daraus entsteht eine Historie der Änderungen, die auf dem History Tab abgerufen werden kann. Dort können auch Vergleiche von zwei Versionen angestellt werden. Führt man einen solchen Vergleich durch, erhält man einen Blick auf das Definitionsformat (JSON).

Fazit

Das neue Build-System bietet einen bequemen Weg, eine CI-Umgebung aufzubauen, ohne sich durch MSBuild-Skripte oder XAML-Build-Skripte zu wühlen. Allerdings ist die Dokumentation, die man dazu im Netz der Netze findet, alles andere als vollständig. Insbesondere die einzelnen Build Step-Typen sind nur spärlich dokumentiert. Gerade was diverse Pfadangaben in den Build Steps betrifft, gilt mehr als einem lieb ist das Prinzip Trial&Error. Aber vielleicht kann dieser Artikel auch ein wenig dazu beitragen, dass der Einstieg in die Thematik leichter fällt.

Xamarin Hackathon

Hackathons sind toll. Und weil das so ist, haben der Chris, der Markus und ich (“die Organisatoren”) einen mit unseren eXperts-Kollegen abgehalten. Ziel war, unsere Erfahrungen mit Xamarin – und im speziellen Xamarin.Forms – mit den Kollegen zu teilen und sie in die Lage zu versetzen, selbst die ersten Schritte in der Cross-Plattform-Entwicklung von Mobile Apps zu gehen.

Aber was ist eigentlich ein Hackathon? Der Begriff erweckt die Assoziation einer motivierenden, ungezwungenen und dennoch zielgerichteten Arbeitsatmosphäre, die eine gute Basis ist für einen nachhaltigen Wissensaustausch unter den Kollegen. Wikipedia meint, dass es sich um eine kollaborative Software- und Hardware-Entwicklungsveranstaltung handele. Dabei werde zunächst ein Thema vorgestellt und dann dazu Umsetzungsvorschläge diskutiert. Im Folgenden werde innerhalb kurzer Zeit ein gemeinsames Produkt erstellt. In diesem umfassenden Sinne fand dies bei uns jedoch nicht statt. Wir hatten den Begriff des Hackathon etwas uminterpretiert…

Unser Hackathon hatte den Charakter eines Workshop, bei dem Wissen und Erfahrungen vermittelt werden. Die Organisatoren hatten ein Beispielprojekt entwickelt, anhand dessen die Arbeit mit Xamarin.Forms demonstriert und erfahren werden sollte. Es ging um eine Mobile App für Android, iOS und Windows Phone. Den Funktionsumfang hielten wir handlich klein, um den einen Tag, den wir für den Hackathon angesetzt hatten, nicht mit fachlichen Diskussionen vollzustopfen. Stattdessen konzentrierten wir uns auf die Technologie. Eben Xamarin.Forms. Dazu gibt es hier im Flurfunk übrigens auch den einen oder anderen Beitrag, der sich zu lesen lohnt.

Die Anforderungen an die zu entwickelnde Anwendung waren überschaubar. Sie sollte eine Liste von Elementen darstellen, welche editiert und gelöscht werden können. Auch das Hinzufügen von Elementen sollte möglich sein. Durch die Liste sollte man scrollen und im Kontext einzelner Listenelemente interagieren können. Bei der Eingabe eines Elements sollten verschiedene Tastatur-Layouts (normal, numerisch) berücksichtigt sowie einfache Validierungen durchgeführt werden.

Als Vorbereitung hatten wir eine Xamarin.Forms Solution angelegt, quasi als Referenzimplementierung, die dann während des Hackathon nach und nach aufgebaut werden sollte. Die Steps dafür hatten die Organisatoren quasi als “roten Faden” durch den Hackathon notiert. Ebenfalls im Vorfeld wurden alle Teilnehmer über die technischen Voraussetzungen informiert. So musste beispielsweise jeder Teilnehmer eine Xamarin-Trial oder -Business-Lizenz zur Verfügung haben. Weiterhin musste Xamarin auf dem Entwicklungsrechner installiert sein und geeignete Emulatoren oder Hardware Devices zum Testen bereitstehen.

Ablauf

Und so haben wir uns morgens neun Uhr zu zehnt in unserem Konferenzraum um einen Tisch versammelt, die Notebooks ausgepackt und losgelegt. Die Organisatoren sorgten per Beamer für ein gemeinsames Bild von Architektur und Code.

Zunächst stellten wir sicher, dass bei allen Teilnehmern die technischen Voraussetzungen gegeben sind. Danach ging es dem “roten Faden” folgend ans Implementieren. Dabei teilten wir den Gesamtumfang der Implementierungsschritte so auf, dass drei Leute nacheinander jeweils einen Teil davon demonstrierten. Ich legte den Grundstein für die Applikation und implementierte das architektonische Grundgerüst. Markus setzte dann fort und demonstrierte plattformspezifische Implementierungen für Windows Phone. Chris schloss daran an und vervollständigte die Applikation am Beispiel der Android-Plattform. Im Ergebnis hatten wir eine lauffähige Software mit dem geplanten Funktionsumfang auf zwei Plattformen zur Verfügung – Windows Phone und Android.

Was ist mit iOS? Dafür kann man doch mit Xamarin auch entwickeln? Selbstverständlich. Leider machte uns an diesem Tag aber Murphy einen Strich durch die Rechnung, indem er verhinderte, dass sich unser MacBook Air ins interne Netz integrierte. Damit stand es als Xamarin Build Host nicht zur Verfügung und wir konnten die iOS App zwar nebenbei mitentwickeln, aber nicht deployen und testen. Da gerade für Einsteiger in Xamarin das Entwicklungs-Setup für die Entwicklung von iOS-Applikationen besonders interessant ist, war es umso ärgerlicher, dass wir das im Hackathon nicht zeigen konnten.

Was wir gelernt haben

Am Ende des Hackathon – so gegen 16:30 – erbaten sich die Organisatoren ein Feedback von den Teilnehmern. Sozusagen was gut und was verbesserungswürdig war. Daraus ergaben sich die folgenden Erkenntnisse.

  • Was das Erklären einer laufenden Implementierung anbelangt, so ist das Zeitempfinden zwischen Teilnehmern und demjenigen, der etwas codiert, stark unterschiedlich. Demonstriert man eine Implementierung, ist man meistens zu schnell für jemanden, der dies zum ersten Mal tut und verstehen sowie nachimplementieren soll. Die Gefahr besteht, dass Teilnehmer “abgehängt” werden. Als Demonstrierender ist man von der Geschwindigkeit dann genau richtig unterwegs, wenn es einem zu langsam vorkommt.
  • Es ist aus didaktischer Sicht unbedingt empfehlenswert, zu Beginn der Veranstaltung die fertige App mit vollem Funktionsumfang vorzustellen, also das Ziel des Hackathon. Zusätzlich hilft es den Teilnehmern während der Veranstaltung dabei, die gerade durchgeführten Aktionen in den richtigen Zusammenhang zu stellen, also zu wissen, warum man gerade dieses und jenes tut.
  • Die gemeinsame Entwicklung der App teilte sich in mehrere Schritte, z. B. das Projekt-Setup, ein erstes Hallo-Welt-Beispiel, Einbinden von Ressourcen, Integration eines Dependency-Injection-Containers, Implementierung von plattformspezifischem und Shared Code. Es ist sehr hilfreich, auch vor jedem dieser einzelnen Schritte darzustellen, was das Ziel dieses Schrittes ist. Damit ist dann auch jedem klar, warum z. B. jetzt ein Interface als Abstraktion angelegt wird und was damit erreicht werden soll.
  • Um sich auf die Technologie zu fokussieren, ist es empfehlenswert, die Fachlichkeit der zu entwickelnden Anwendung klein zu halten.

Fazit

Die Technologielandschaft im Bereich der Software-Entwicklung ist bekanntermaßen immer dynamischeren Veränderungen unterworfen. Kein Mensch kann mehr in allen Themen selbst fit sein oder hat die Zeit, sich von Grund auf fit zu machen. Dafür ist das Umfeld zu komplex, zu groß die Auswahl der Technologien, zu gering die zur Verfügung stehende Zeit.

Es braucht also auch andere Wege als “Selbststudium”, um neben der eigentlichen Arbeit up-to-date zu bleiben. Wir in der SDX haben dafür bereits unterschiedliche Formate etabliert, um für Wissenstransfer innerhalb des Unternehmens zu sorgen. So halten eXperts regelmäßig zu unterschiedlichsten Themen kleine Vorträge und führen Diskussionsrunden, so am Abend, mit Pizza und Bier. Zu diesem Portfolio an Möglichkeiten der Wissensvermittlung stoßen immer mehr auch die Hackathons.

Alles in allem ist so ein Hackathon eine hervorragende Art und Weise, um noch fokussierter und intensiver Wissen zwischen eXperts auszutauschen. Und zwar hands-on, unmittelbar, praktisch, am Code. Man kann damit sehr gut Hürden abbauen, sich selbst mit neuer Technologie auseinanderzusetzen. Und die Dauer von einem ganzen Tag sorgt dafür, dass sich jeder Teilnehmende wirklich einen Tag ausschließlich der jeweiligen Thematik widmen kann.

Unsere Erfahrungen mit diesem Hackathon sind durchweg positiv. Wir haben einiges gelernt, was wir noch besser machen können. Und wer weiß, vielleicht laden wir mal zu einem öffentlichen Hackathon ein, damit auch Du mal ein bisschen SDX-Luft schuppern kannst und hoffentlich Neues mit nach Hause nimmst.

Xamarin.Android und die Android API Levels

Bei der Konfiguration von Xamarin.Android-Projekten kann eingestellt werden, welche Android API Levels angewendet werden. So kann man festlegen, gegen welches Level kompiliert wird, welches Level auf dem Zielgerät mindestens vorausgesetzt wird und für welches Level die Anwendung eigentlich geschrieben wird. Dieser Artikel beleuchtet die Anwendung der Android API Levels im Kontext von Xamarin for Visual Studio. Da eine fehlerhafte Kombination von API Levels zum Crash der App führen kann, ist ein gutes Verständnis dafür sehr empfehlenswert.

Seitdem mit Xamarin bzw. Mono die Möglichkeit besteht, mit den Standard-Windows Entwicklerwerkzeugen (Visual Studio, C#) Anwendungen für Android zu erstellen, kommen auch .NET-Entwickler in den Genuss der Entwicklung von Android Apps. Um den Einstieg in die Thematik der Android API Levels zu erleichtern, beschreibt dieser Artikel den grundsätzlichen Umgang damit.

Ein API Level ist zunächst einmal nur eine Ganzzahl. Angefangen bei Level 1 ist zum Zeitpunkt der Entstehung dieses Artikels das aktuellste API Level 22. Jede neue Android-Version (aktuell v5.1 “Lollipop MR1”) bringt i. d. R. eine neue Revision der Android Framework API mit, welche durch das API Level gekennzeichnet wird. Die Framework API wird von Android Apps genutzt, um mit der Android Platform zu interagieren. Immer dann, wenn eine neue Android-Version Updates an der mitgelieferten API vornimmt, wird die Nummer des API Levels erhöht.

Updates an der Framework API sind abwärtskompatibel, so dass ältere Anwendungen weiterhin lauffähig bleiben. Updates sind additiv, d. h. wenn alte Bestandteile der API aktualisiert werden, so werden diese nicht entfernt, sondern nur als veraltet gekennzeichnet. Nur in wenigen Fällen, z. B. im Rahmen von Security Updates), kann es sein, dass API-Teile tatsächlich geändert oder sogar entfernt werden.

Jede Version der Android Platform unterstützt genau ein API Level, wobei aber immer frühere Levels implizit unterstützt werden. Die Android Developer Website enthält eine gute Übersicht über Android-Versionen und deren unterstütze API Levels.

Über die Verteilung der verschiedenen Android-Versionen und API Levels über den Android-Gerätemarkt liefern die Android Dashboards eine gute Übersicht. Gegenwärtig machen die Android-Versionen 4.1 bis 4.4 (JellyBean und Kitkat zu ähnlichen Anteilen) ca. 80% des Marktes aus (vgl. Android Dashboards). Lollipop (API Level 21 & 22) ist mit ca. 10% im Kommen. Damit sind die API Levels 16 bis 19 am stärksten im Markt vertreten, wobei 19 (Android 4.4 “Kitkat”) für sich genommen den Löwenanteil ausmacht. Wenn man also Apps für Android erstellt. Sollte man mindestens API Level 16 unterstützen, um den allergrößten Anteil der Geräte im Markt zu abzudecken.

Doch nun zum praktischen Teil.

Eingestellt werden die API Levels in einem Xamarin.Android App Visual Studio Project in den Projekteigenschaften im Bereich Application.

ProjectProperties

  • Bei "Compile using Android version" handelt es sich um das Target Framework, gegen das die App kompiliert wird.
  • "Minimum Android to target" meint die Minimum Android Version, also die kleinste Android-Version, die die App mindestens auf dem Zielgerät voraussetzt.
  • Die "Target Android Version" meint das API Level, für das die App primär programmiert wird.

Welche API Levels jeweils zur Auswahl stehen hängt davon ab, welche auf dem Entwicklungsrechner installiert sind. Die Installation erfolgt mit dem Android SDK Manager.

Die drei Einstellungen im Visual Studio Project werden im Folgenden näher erläutert.

Target Framework

Das Target Framework bezeichnet das API Level zur Entwicklungs-/Kompilierzeit und somit das API Level, gegen das die App vorweg geprüft und übersetzt wird. Das hier eingestellte Level bewirkt, dass die Anwendung zur Laufzeit davon ausgeht, dass dieses Level und dessen Funktionsumfang zur Verfügung stehen. Es sagt jedoch nichts darüber aus, welches Level zur Laufzeit tatsächlich verfügbar ist.

Aus dem eingestellten Target Framework ergeben sich die APIs, die zur Entwicklungszeit zur Verfügung stehen. Wird eine API-Funktion aufgerufen, die erst in einem höheren API Level als das eingestellte zur Verfügung steht, wird bereits vom Compiler ein Fehler gemeldet.

Target Android Version

Die Target Android Version bezeichnet das API Level, von dem die Anwendung ausgeht, dass es zur Laufzeit verfügbar ist. Dies ist somit die Android-Version, für die die App gedacht ist und primär entwickelt wird. Die App kann sich darauf verlassen, dass alle Funktionen dieser Version auf dem Zielgerät vollständig vorhanden sind und kann diese auch vollständig nutzen. Beim Deployment wird geprüft, ob die eingestellte Version auf dem Zielgerät vorhanden ist. Falls sie nicht vorhanden ist, wird sie beim Deployment bzw. der Installation aus dem Store mit eingeschlossen.

Normalerweise wird die Target Android Version dem Target Framework entsprechen. Es gibt allerdings Ausnahmen. So könnte eine verwendete Android Library eine höhere Target Android Version voraussetzen. In diesem Fall müsste für die App die Target Android Version höher eingestellt werden als das Target Framework.

Die Target Android Version signalisiert der Android Runtime, dass die App gegen dieses API Level erfolgreich getestet wurde. Das bedeutet für Android, dass keine besondere Kompatibilitätslogik ausgeführt werden muss, um die App auf einem Gerät mit diesem API Level auszuführen. Im anderen Fall, wenn das API Level auf dem Zielgerät höher ist als die Target Android Version der App, würde Android durch spezielles Verhalten für die Aufwärtskompatibilität der App sorgen.

Minimum Android Version

Dies ist die auf dem Zielgerät mindestens vorausgesetzte Android-Version. Wird diese niedriger eingestellt als das Target Framework, signalisiert dies die Abwärtskompatibilität der App.

Falls die App APIs aufruft, die in der Minimum Android Version noch nicht existieren, crasht die App zur Laufzeit. Es ist daher notwendig, dass im Code entsprechende Runtime Checks eingebaut werden, die eine bestimmte API nur dann aufrufen lassen, wenn diese auch vorhanden ist. Mono.Android enthält dafür entsprechende Hilfsklassen.

Runtime Checks

Setzt man die Minimum Android Version auf einen niedrigeren Wert als das Target Framework, könnten einige der im Code aufgerufenen APIs zur Laufzeit nicht verfügbar sein. Trotzdem könnte die App auf einem älteren Gerät laufen, dann allerdings ohne Verfügbarkeit bestimmter Features. Der Code der App muss in diesem Fall dafür Sorge tragen, dass nur die APIs aufgerufen werden, die auch verfügbar sind. Wie macht er das?

Die Assembly Mono.Android enthält dafür das abzufragende Property Android.OS.Build.Version.SdkInt, welches den BuildVersionCode zurückgibt. Ein konkreter Runtime Check, der z. B. prüft, ob mindestens Android 4.4 (Kitkat) vorliegt, sieht dann wie folgt aus:

   1: if (Android.OS.Build.Version.SdkInt >= Android.OS.BuildVersionCodes.Kitkat) 

   2: {

   3:

   4: }

Im Falle die erstellte App läuft in einer veralteten Umgebung, könnte die App z. B. den Benutzer informieren, dass ein bestimmtes Feature nicht zur Verfügung steht. Oder das bestimmte Feature wird stillschweigend nicht angeboten. Oder die App enthält eine Alternativimplementierung. Oder… Hier ist sicher die Kreativität des Entwicklers gefragt unter Berücksichtigung der User Experience. 😉

API Level-Kombinationen

Bei der Wahl der API Levels sind Regeln zu beachten. So macht es beispielsweise keinen Sinn, gegen ein niedrigeres Target Framework zu kompilieren, als auf dem Zielgerät mindestens vorausgesetzt wird (Minimum Android Version). Oder auch gegen ein höheres Target Framework zu kompilieren, als Android durch die Target Android Version tatsächlich sicherstellt, ist nicht zulässig.

 

Target Framework (TF) =

Minimum Android Version (Min) = Target Android Version (TAV)

Normalfall.

Ein Xamarin.Android-Projekt enthält diese Kombination standardmäßig bei der Erstellung durch das Projekt-Template. Hier besteht keine Abwärtskompatibilität.

TF < Min

Nicht zulässig, da dies zu Inkompatibilität führt.

TF > Min

Abwärtskompatibilität der App, um ältere Android-Versionen zu unterstützen. Erfordert Runtime Checks im Code, um nicht unterstützte API-Aufrufe auf der jeweiligen Zielplattform zu verhindern.

TF < TAV

Empfohlen, wenn verwendete Bibliotheken ein höheres API Level voraussetzen (entspricht dem Target Framework der Bibliotheken).

TF > TAV

Nicht zulässig, da dies zu Inkompatibilität führt.

Min < TAV

Ist dann der Fall, wenn TF >= TAV ist und Abwärtskompatibilität entsprechend TF > Min gewährleistet werden soll.

Min > TAV

Nicht zulässig, da dies expliziter Aufwärtskompatibilität entsprechen würde und somit im Widerspruch zum umgesetzten Ansatz der Kompatibilitätssicherung stünde.

Bei unzulässigen Kombinationen warnt Visual Studio.

Warnungen

Android Libraries

Ein Xamarin.Android Class Library Project enthält im Gegensatz zu App Projects keine Möglichkeit zur expliziten Auswahl von Minimum und Target Android Version.

Library

Der Grund dafür ist, dass die Library in beliebigen Apps verwendet werden könnte, die für beliebige API Levels erstellt werden. Minimum und Target Android Version werden also von der App bestimmt, die die Library verwendet. Bei der Verwendung oder Erstellung von Android Libraries sollte demnach Folgendes beachtet werden.

  • Wenn eine Library konsumiert wird, sollte die Target Android Version mindestens so hoch sein, wie das Target Framework Level der Library. Das gilt im Übrigen auch für die Minimum Android Version, da man nicht wissen kann, dass die Library ein niedrigeres Level unterstützt als das, wogegen sie kompiliert worden ist.
  • Wenn eine Library erstellt wird, sollte deren Target Framework Level nicht höher als nötig eingestellt werden. Es ist gilt als Best Practice, dass man sich bei der Entwicklung einer Library auf die Verwendung möglichst weniger API Calls beschränkt, um die Library auf möglichst vielen API Levels schlussendlich verwenden zu können.

Fazit

Ein gutes Verständnis der Android API Levels ist notwendig. Es vermeidet Fehler, die erst zur Laufzeit auffallen und im schlimmsten Fall bis zum Endanwender durchschlagen sowie nur durch ein erneutes Deployment in den Store behoben werden können. Abschließend und zusammenfassend seien folgende Tipps gegeben.

  • Verwende für Target Framework, Target Android Version und Minimum Android Version standardmäßig das gleiche API Level. Weiche davon nur ab, wenn es gute Gründe dafür gibt, wie z. B. Abwärtskompatibilität zu gewährleisten.
  • Setze das Target Framework Level nur so hoch, wie für Deine App notwendig, wenn so viele Geräte wie möglich unterstützt werden sollen.
  • Beachte die Besonderheiten bei der Erstellung und dem Konsum von Android Libraries.

Siehe auch

Understanding Android API Levels (Xamarin Developer Portal)http://developer.xamarin.com/guides/android/application_fundamentals/understanding_android_api_levels

<uses-sdk> | Android Developers

http://developer.android.com/guide/topics/manifest/uses-sdk-element.html