Azure-RoleEntryPoint in eigenes Assembly auslagern

23. Mai 2011

Azure-Projekte beziehen sich auf eine oder mehrere Roles, wobei eine Role ein Template für die VM-Instanzen im Microsoft-Rechenzentrum ist. Jede Role braucht nun eine Klasse, welche von RoleEntryPoint ableitet (für WebRoles optional – siehe RoleEntryPoint Class) und in der Azure-Role-spezifische Events behandelt werden. Standardmäßig wird diese Klasse bei einer WebRole im primären Web-Projekt angelegt, so dass dieses Projekt mit Referenzen auf die Assemblies „Microsoft.WindowsAzure.Diagnostics“ und „Microsoft.WindowsAzure.ServiceRuntime“ versehen werden muss – etwas, was man gerne vermeiden möchte, wenn das Web-Projekt sowohl in Azure als auch On-Premise gehostet werden soll.

Das Auslagern dieser Klasse in ein gesondertes Assembly scheitert daran, dass Azure in der Text-Datei „__entrypoint.txt“ die Angabe des Assemblies erwartet, welches den Role-Entry-Point enthält (siehe auch “Cloudy in Seattle” Post vom Feb 2010) … diese Datei wird aber hart auf das primäre Output-Assembly gesetzt, welches im Falle einer Web-Role eben das Web-Projekt ist – sehr unschön und ggf. ein Punkt der in einem Service-Pack beseitigt werden sollte.

Ein einfacher Weg, das trotzdem hinzubekommen ist, die Datei nach dem Build-Vorgang (im Post-Build-Event des Azure-Projekts) zu verändern bzw. zu überschreiben. Ich nutze in einem aktuellen Projekt dazu eine Batch-Datei mit folgendem Eintrag als „Post-build event command line“:

1: $(ProjectDir)..AzureCopyRoleEntryPointHint.bat $(ProjectDir)

Der Inhalt der Batch-Datei lautet hierbei:

1: copy %1..Azure __entrypoint.txt MeinAzureProjekt.csx
olesMeinWebProjekt\__entrypoint.txt

2: copy %1..MeinAzureProjekt.RoleAddOninDebugMeinAzureProjekt.RoleAddOn.dll            MeinAzureProjekt.csx
olesMeinWebProjektapprootin
3: copy %1..MeinAzureProjekt.RoleAddOninDebugMicrosoft.WindowsAzure.Diagnostics.dll    MeinAzureProjekt.csx
olesMeinWebProjektapprootin
4: copy %1..MeinAzureProjekt.RoleAddOninDebugMicrosoft.WindowsAzure.ServiceRuntime.dll MeinAzureProjekt.csx
olesMeinWebProjektapprootin
5: copy %1..MeinAzureProjekt.RoleAddOninDebugMicrosoft.WindowsAzure.StorageClient.dll  MeinAzureProjekt.csx
olesMeinWebProjektapprootin

Wichtig hierbei:

  • Da das Azure-Projekt die WebSite referenziert und keine zusätzlichen Dateien aufnehmen kann, müssen die zusätzlichen Dateien (vorbereitete „__entrypoint.txt“ und die Batch-Datei) in ein gesondertes Verzeichnis aufgenommen werden (hier das „Azure“-Verzeichnis im Solution-Verzeichnis).
  • In den Eigenschaften der Solution sollte die Abhängigkeit des Azure-Projekts zum RoleEntryPoint-Assembly eingetragen werden, damit das Assembly auf jeden Fall vorher gebuildet wird.
  • Das Ausführungs-Verzeichnis für den Post-Build-Step ist das Target-Verzeichnis des Builds – das kann gerade bei Einsatz eines TFS-Build bei der Nutzung von relativen Pfad-Angaben zu Problemen führen (daher die Übergabe des „$(ProjectDir)“ als Parameter für die Batch-Datei). Je nach Build-System müssen hier noch Anpassungen vorgenommen werden.
  • Der Inhalt der „__entrypoint.txt“ muss in diesem Falle „binMeinRoleAddOn.dll“ (also der relative Pfad zum Assembly der RoleEntryPoint-Klasse ohne „Release“/“Debug“) lauten. Die Angabe der Build-Konfiguration darf nicht enthalten sein, da diese Datei in der Azure-VM Verwendung findet – und da gibt es nur das bin-Verzeichnis.
  • Das einfache Kopieren von ein paar Dateien macht leider noch keine vollständige Azure-Applikation aus. Zusätzlich müssen auch die Konfigurationen in der Web.Config korrekt sein und die Azure-Infrastruktur konfigurieren (z.B. der DiagnosticsConnectionString). Hier kann eine “Config Transform” helfen.
  • Da keine Projekt-Referenz auf das RoleEntryPoint-Projekt besteht, muss die Kopier-Batch-Datei ggf. noch erweitert werden – Abhängigkeiten des RoleEntryPoint-Projekt müssen ebenfalls in diese Datei aufgenommen werden.

Generell ist es eine gute Idee, Abhängigkeiten zu speziellen Umgebungen (Datenbanken, Services, Azure) aus den allgemeineren Projekten heraus zu halten (separation of concerns) und diese Abhängigkeiten zu abstrahieren. Um dies auch in Bezug auf Azure zu schaffen, bietet die hier beschriebene Vorgehensweise eine (relativ) einfache Möglichkeit. So wird es möglich, in Azure den Role-Entry-Point zu nutzen und gleichzeitig die Kompatibilität zum In-House-Hosting der Anwendung sicher zu stellen.