.NET Core App unterscheiden zw. Development und Production



  • Hallo zusammen,

    ich entwickle zwei Apps in C# mit .NET Core 3.1, eine "Web Application" und eine "WebAPI Application". Im Moment entwickle ich lokal, und später sollen die Apps in Window Azure jeweils als "Azure App" ausgerollt werden.

    Todo: mein Code in C# soll ermitteln, ob er
    a) bei mir lokal ausgeführt wird, oder
    b) in Azure.

    Die Docs von Microsoft beschreiben die Verwendung einer Projektvariablen des Typs String namens "ASPNETCORE_ENVIRONMENT" in Visual Studio, welche "Development" oder "Production" beinhaltet.
    Damit habe ich auch den ersten Schritt in Richtung Ziel, aber leider nicht ganz, und im WWW werde ich nicht fündig zu mehr Informationen.

    Mein Problem ist, dass diese Projektvariable nur zur Verfügung steht während des Startup-Prozesses beider Applications, danach nirgendwo mehr. Wenn beide Apps in Betrieb sind, dann ist das Startup vorbei und erledigt, und alle Funktionen beider Apps (die Webpages und die Webservices) haben jeweils keinerlei Kenntnis über irgendeine Projektvariable.

    a) Meine Web Application hält mehrere Webseiten mit ihrem eigenen "code behind" (cshtml.cs) vor.
    Wie kommt der C# Code dort legal an die Projektvariable heran um halt unterscheiden zu können zwischen Dev und Prod?

    b) Der Controller meiner WepAPI (es existiert im Moment nur einer) hält mehrere GET und POST Servicenafragen vor.
    Wie kommt der C# Code im Controller legal an die Projektvariable heran?

    Nirgendwo finde ich Hinweise zu genau diesem speziellen Problem, und das kann eigentlich garnicht sein finde ich. 😉

    Einen Weg hätte ich natürlich, nämlich dass ich selber die Projektvariable während des Startups irgendwie global innerhalb der jew. Application bereitstelle, z.B. als öffentliche statische Member der Startup-Klasse selbst.

    Aber ist das der im App-Design beabsichtigte und richtige Weg das so zu tun? Kein "offizieller" Weg?

    Beides sind übrigens "ASP.NET Core Web Applications" - ebenfalls erstellt dem jew. Zweck entsprechend nach Anleitung in den MS Docs. Soweit habe ich alles richtig gemacht.

    Vielen Dank vorab!

    Hoppelmoppel



  • Es gibt wie vermutet eine technische Lösung, und sie heisst "depency injection" (DI).
    Genauer beschrieben wird sie hier in den MS Docs:
    Environment-based startup class and methods

    Die Unterscheidung "development | production" (oder mehr wie z.B. "staging") wird in Visual Studio 2019 als String hinterlegt in "Projekteigenschaften / Debug / Environment variables":

    Name
    ASPNETCORE_ENVIRONMENT
    
    Value
    Development
    

    Sowohl in der "startup.cs" der Azure App als auch den Azure App Pages "*.cshtml.cs" werden diese Namensräume hinzugefügt:

    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Hosting;
    

    Allen Methoden der "startup.cs" kann das "IWebHostEnvironment" Interface hinzugefügt werden:

    		public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    		{
    			if (env.IsProduction())
    			{
    				// do something
    			}
    			else if (env.IsDevelopment())
    			{
    				// do something
    			}
    		}
    

    Die Model-Klasse einer Page (bei mir "class IndexModel : PageModel") bekommt eine neue Eigenschaft:

            private readonly IWebHostEnvironment Env;
    

    und dessen Konstruktur einen neuen Parameter:

    		public IndexModel(IWebHostEnvironment env)
    		{
    			this.Env = env;
    		}
    

    So erhält auch die Page die Umgebungsvariable.

    Mit DI werden auch andere Objekte weitergereicht innerhalb einer Azure App, z.B. die "appsettings.json".

    Hoppelmoppel