2017-09-28 1 views
0

Ich habe zwei Konfigurationsdateien:Wie wird eine Konfigurationsquelle in einen bestimmten Konfigurationsabschnitt platziert, um Schlüsselkonflikte zu vermeiden?

users.json:

{ 
    "Alice" : { "Email": "[email protected]" }, 
    "Bob" : { "Email": "[email protected]" } 
} 

und connections.json

{ 
    "Database" : { "ConnectionString": "..." }, 
    "Gateway" : { "Url": "http://..." } 
} 

Und ich versuche, eine einzelne Konfiguration Wurzel zu komponieren:

var cfg = new ConfigurationBuilder() 
    .AddJsonFile("users.json") 
    .AddJsonFile("connections.json") 
    .Build(); 

Offensichtlich Ich muss p schnappen Sie jede Konfigurationsquelle in den Abschnitt: Users und Connections - um Konflikte zu vermeiden. Eine Art Prefixing Wrapper kann die Aufgabe erledigen, aber ich möchte nicht meine eigenen implementieren.

Wie würden Sie mit dieser Situation umgehen, wenn Sie die Struktur der Konfigurationsdatei nicht ändern können (im realen Projekt gibt es dafür einen Grund)?

Antwort

0

Sie Ihre JSON-Dateien ändern können Abschnitte reflektieren:

users.json:

{ 
    "Users": { 
     "Alice" : { "Email": "[email protected]" }, 
     "Bob" : { "Email": "[email protected]" } 
    } 
} 

und connections.json

{ 
    "Connections": { 
     "Database" : { "ConnectionString": "..." }, 
     "Gateway" : { "Url": "http://..." } 
    } 
} 
+0

Das ist leicht zu argumentieren gegen Konfiguration DE- Normalisierung im Allgemeinen, aber in meinem Fall ist es einfach keine Option, diese Dateien zu ändern – astef

2

entsprechend JsonConfigurationFileParser und JsonConfigurationProvider Klassen Umsetzung aussieht wie du nur darf eigene FileConfigurationProvider Implementierung schreiben.


Als Abhilfe können Sie die folgende (Schritt für Schritt) tun kann:

  • => Konfigurationen pro Datei lesen
  • => dann als eine Sammlung von KeyValuePair Artikel führen erhalten
  • => Dann fügen Sie jedem Schlüsselnamen ein benutzerdefiniertes Präfix hinzu (in Ihrem Fall basierend auf dem Dateinamen)
  • => Zusammenführen: Die letzte Sammlung als MemoryCollection-Quelle an die Stammkonfiguration anhängen

Der folgende Code ist die Idee, Umsetzung und kann geändert werden müssen, bevor sie in prod mit:

public static class ConfigurationBuilderExtensions 
{ 
    public static IConfigurationBuilder AddJsonFileWithPrefix(this IConfigurationBuilder configurationBuilder, string fileName, string prefix) 
    { 
     var config = new ConfigurationBuilder() 
      // you may need to set up base path again here 
      // .SetBasePath(Directory.GetCurrentDirectory()) 
      .AddJsonFile(fileName).Build(); 

     var result = new List<KeyValuePair<string, string>>(); 

     foreach(var pair in config.AsEnumerable()) 
     { 
      result.Add(new KeyValuePair<string, string>($"{prefix}:{pair.Key}", pair.Value)); 
     } 

     return configurationBuilder.AddInMemoryCollection(result); 
    } 
} 

dann können Sie Konfiguration root als erstellen:

var cfg = new ConfigurationBuilder() 
    .AddJsonFileWithPrefix("users.json", "users") 
    .AddJsonFileWithPrefix("connections.json", "connections") 
    .Build(); 
+1

Danke für Ihre Probe. Nur ein paar Probleme für den Fall, dass Sie es verbessern: 1) Reload-Mechanismus wird nicht funktionieren; 2) es ist möglich, es allgemeiner zu machen (um nicht nur mit json zu arbeiten) – astef

Verwandte Themen