Fabasoft
Dynamically created OData Datasource
Description
Gerald Leitner von Fabasoft spricht in seinem devjobs.at TechTalk über das Thema „Dynamically created OData Datasource“. Anhand eines Beispiels in einer Live-Coding Session, werden verschiedene Aspekte demonstriert.
Beim Videoaufruf stimmst Du der Datenübermittlung an YouTube und der Datenschutzerklärung zu.
Video Zusammenfassung
In Dynamically created OData Datasource zeigt Gerald Leitner (Fabasoft), wie man OData in ASP.NET 5 zunächst klassisch aktiviert (Microsoft.AspNetCore.OData 7.x, AddOData, ODataConventionModelBuilder, EnableQuery und ein Key im Modell) und dann radikal dynamisiert. Per Middleware werden aus JSON-Metadaten zur Laufzeit Controller und Entitäten generiert, mit Roslyn kompiliert, via Application Parts registriert, die Route transformiert und das OData-EDM neu aufgebaut – inklusive $metadata und Query-Optionen wie $top. Das Demo liefert sprachspezifische Endpunkte (z.B. Deutsch/Katze, Englisch/Cat) und zeigt, wie sich hochflexible, erweiterbare OData-APIs für Tools wie Power BI umsetzen lassen.
Dynamische OData-Datenquelle in ASP.NET 5: Wie Gerald Leitner (Fabasoft) OData-Modelle und -Controller zur Laufzeit generiert
Überblick: Von statischem Beispiel zur maximalen Flexibilität
In der Session „Dynamically created OData Datasource“ mit Speaker Gerald Leitner (Fabasoft) ging es um ein ambitioniertes Ziel: OData nicht nur „klassisch“ mit statischen Modellen und fix eingebauten Controllern zu betreiben, sondern zur Laufzeit dynamisch zu erzeugen – inklusive Modell, Controller, OData-Registrierung und Routen-Transformation. Oder, wie Leitner es formuliert: „Wir wollen die größtmögliche Flexibilität, die Dynamik in die OData reinbringen.“
Wir von DevJobs.at haben die Live-Demo verfolgt – vom bekannten „WeatherForecast“-Template über die Aktivierung von OData 7.x und Query-Optionen bis hin zum Herzstück: einer Middleware, die bei eingehenden Requests Sprache und Ressource erkennt, Quellcode generiert, mit dem C#-Compiler zur Laufzeit Assemblies baut, als Application Part in die laufende ASP.NET-Anwendung einhängt, die Routen umschreibt und OData das passende EDM-Modell zur Verfügung stellt. Das Ergebnis sind sprachspezifische Endpunkte wie „/deutsch/katze“ oder „/englisch/cat“, die eigene Models, Controller und OData-Metadaten liefern – vollständig zur Laufzeit erzeugt.
Kurz zu OData und dem Ausgangspunkt
Leitner ordnete OData zunächst ein: OData ist ein HTTP-basiertes Protokoll zur standardisierten Datenabfrage – ideal, wenn man große Datenmengen über einheitliche Schnittstellen für Tools wie Power BI bereitstellen möchte. Der Standard wird von OASIS weiterentwickelt; aktuell ist OData 4.0 relevant. In der Praxis bedeutet das: Clients können per URL-Query-Optionen wie „$top“, „$filter“, „$orderby“ und Co. serverseitig vorkonfigurierte Datenquellen flexibel abfragen.
Als Ausgangssituation diente das standardmäßig generierte ASP.NET-Template mit einem „WeatherForecast“-Modell und -Controller. Dieser liefert zufällig generierte Daten als JSON. Noch ohne OData – und damit natürlich ohne die bekannten Query-Features oder Metadaten.
Schritt 1: OData im statischen Projekt aktivieren (7.x)
Bevor es in die dynamische Welt geht, aktivierte Leitner OData im statischen Beispiel. Das half, die Bausteine und Anforderungen zu verstehen, die später dynamisch nachgebildet werden müssen.
- Paket: Er ergänzte „Microsoft.AspNetCore.OData“ (Version 7.x). 8.0 existiert als Preview, unterscheidet sich aber im Handling – daher die Live-Demo mit 7.x.
- Services: In „Startup“ wird OData via „AddOData“ aktiviert.
- Endpoints: In „UseEndpoints“ werden OData-Features eingeschaltet – konkret „Select“, „Filter“, „Count“, „Top“. Zudem wird eine OData-Route registriert, etwa unter „/odata“.
- EDM-Modell: OData benötigt ein Modell. Leitner erzeugte es über den „ODataConventionModelBuilder“. Wichtig: Per „EntitySet“ wird festgelegt, welche Entitäten dem OData-Modell hinzugefügt werden (z. B. „WeatherForecast“). So lässt sich ein größeres Domainmodell gezielt zuschneiden.
- Controller: Aus dem vorhandenen Controller wird ein OData-Controller. Zentral sind das Attribut „EnableQuery“ auf der Methode sowie ein „Key“ im Modell (Primary Key). In der Demo diente das Datum als Key.
Der Effekt: Unter „/odata/weatherforecast“ liefert der Controller Daten inklusive OData-Metadaten. Via „$top=1“ oder „$orderby=Date“ lassen sich die Antworten filtern und sortieren. In der Metadaten-URL erkennt man, welche Entitäten und Eigenschaften das Modell umfasst.
Warum diese statische Aktivierung wichtig ist? Sie präzisiert die Anforderungen an das dynamische Szenario: OData will ein Modell (IEDM), braucht Controller-Endpunkte, Query-Features, eine Route – und in der Praxis müssen diese Dinge korrekt zusammenkommen.
Zielbild: Alles dynamisch – Modell, Controller, Route, OData-Registrierung
„Wir wollen uns von dem statischen Modell und die statischen Controller wegbewegen auf eine extrem dynamische Anwendung“, fasst Leitner das Ziel zusammen. Das Big Picture:
- Die Anwendung startet ohne vordefinierte OData-Entitäten und Controller.
- Ein eingehender Request – etwa „/deutsch“ oder „/deutsch/bär“ – triggert eine Middleware.
- Diese Middleware analysiert Sprache und Ressource, lädt die dafür nötigen Metadaten (in der Demo aus JSON-Dateien wie „katze“ und „bär“), generiert C#-Code für Model und Controller, kompiliert diesen zur Laufzeit zu einer Assembly, hängt sie als Application Part in die laufende App, teilt dem Routing die neuen Controller mit, schreibt die Route um und gibt OData ein dynamisch aufgebautes EDM-Modell.
- Das Ergebnis: Sprach- und ressourcenspezifische Endpunkte, die vollständig zur Laufzeit entstehen und trotzdem die vollen OData-Fähigkeiten (inklusive Metadaten) bieten.
Die Pipeline im Detail: Middleware als Orchestrator
Der Kern liegt in einer selbst geschriebenen Middleware, die Leitner im „Configure“ (Startup) via „UseMiddleware“ einbindet. Sie übernimmt mehrere Aufgaben:
1) Request-Analyse