ASP.NET Core Depedency Injected Config

Als ASP.NET Webentwickler kennt man die XML basierte Konfigurationsdatei web.config. Sozusagen eine Konvention (convention over declaration). Aber die Redmonder Entwickler haben die OWIN Middleware unter diversen Eindrücken an JSON orientiert und nehmen als Format entsprechendes. Allerdings ist das natürlich plug and play konfigurierbar, so das man auch wenn man wollte wieder XML nutzen kann. Umgesetzt wird die das mit dem Entwurfsmuster Dependency Injection. Dabei wird ein Objekt statt mit new mit einem sogenannten DI Container instanziert. ASP.NET Core bringt einen eigenen Container mit der in der Startup.cs Klasse die Methode ConfigureServices aufruft. Als erster und einziger Parameter gibts die Collection der injizierten Services.

public void ConfigureServices(IServiceCollection services)

Das alles statt einem einfachen new class oder meinetwegen statischer Methode. Warum nur? Weil die Welt heute Wert auf Unit Tests legt und man nur so die Entkopplung hinbekommt. Wer das nicht benötigt muss mit diesem Overhead eben leben.

Klassen so hinzugefügt werden als Service bezeichnet. Mit AddSingleton wird eine Instanz erzeugt, mit Addtransient jedes mal eine Neue. Als Typparameter dient das Interface, das die Klasse (als 2ter Parameter) die das Interface implementiert. Hier Configuaration.

 

   1:  services.AddTransient<ppedvService>();
   2:  services.AddSingleton<IConfiguration>(Configuration);

Als Standard Konfigurationsdatei legt Visual Studio die Datei appsettings.json an, die um ein Schlüssel- Wert Paar ergänzt wird.

   1:  {
   2:    "Logging": {
   3:      "LogLevel": {
   4:        "Default": "Warning"
   5:      }
   6:    },
   7:    "AllowedHosts": "*",
   8:    "ppedv": "demo"
   9:  }

Wie nutzt man nun den so deklarierten Service? Per Dependency Injection (DI). ASP.NET Core nutzt unterschiedliche Arten wie Parameter oder Konstruktor Injection. Dabei wird einem Klassen Konstruktor oder einer Methode ein Parameter mitgegeben, den es gar nicht gibt. Eine Razor Page ist auch eine Klasse, die in der Regel die OnGet Methode aufweist. Im C# Beispiel wird der Configuration Service angegeben. Damit nicht die totale Verwirrung herrscht, muss das FromServices Attribut vorgestellt werden. Im Beispiel werden gleich zwei Services injected.

   1:   public class ppedvRzorModel : PageModel
   2:   {
   3:     public void OnGet([FromServices]ppedvService pp,[FromServices] IConfiguration configuration)
   4:       {
   5:        var data = configuration.GetSection("ppedv").Value;
   6:        var html = pp.AddDom();

Erst jetzt kann die MethodeGetSection auf den Knoten der Json Datei zugreifen. Wenn der Inhalt geschachtelt ist wird in einer Doppelpunkt Notation auf die Segmente zugegriffen. Für SQL Connection Strings sollte die Methode GetConnectionString eingesetzt werden.

Um direkt in den Razor VIew zu injezieren nutzt man das @inject.

   1:  @inject ppedvService pp
   2:  ....
   3:      @pp.AddDom()

Die selbst erstellte Service Klasse braucht nichts spezielles. Das folgende Beispiel ist ein einfacher HTML Renderer, praktisch ein Custom Control, das wiederrum auf die Settings zugreift.

   1:  using Microsoft.AspNetCore.Html;
   2:  using Microsoft.AspNetCore.Mvc;
   3:  using Microsoft.Extensions.Configuration;
   4:  using System;
   5:  using System.Collections.Generic;
   6:  using System.Linq;
   7:  using System.Threading.Tasks;
   8:   
   9:  namespace aspnetcoreupload
  10:  {
  11:      public class ppedvService
  12:      {
  13:          IConfiguration _configuration;
  14:          public ppedvService([FromServices] IConfiguration configuration)
  15:          {
  16:              _configuration = configuration;
  17:          }
  18:       
  19:          public HtmlString AddDom()
  20:          {
  21:              
  22:              return new HtmlString($@"<div>Test{ _configuration.GetSection("ppedv").Value}</div>");
  23:          }
  24:      }
  25:  }

Dependency Injection erzeugt auf den ersten Blick Overhead und Komplexität. Sparsam eingesetzt hilft es bessere Testpläne zu erstellen und bringt flexiblere Software Architektur. Wie immer macht es die Dosis. Weniger ist manchmal mehr.

Kommentare sind geschlossen