Pregunta

Realmente quiero poder tener una manera de tomar una aplicación que actualmente obtenga su configuración usando ConfigurationManager.AppSettings [" mysettingkey "] para que la configuración provenga de una base de datos centralizada. del archivo app.config. Puedo crear una sección de configuración personalizada para manejar este tipo de cosas, pero realmente no quiero que otros desarrolladores de mi equipo tengan que cambiar su código para usar mi nueva sección personalizada de DbConfiguration. Solo quiero que puedan llamar a AppSettings como siempre lo han hecho, pero que se carguen desde una base de datos central.

¿Alguna idea?

¿Fue útil?

Solución

Si no te importa piratear el marco y puedes asumir razonablemente la versión de .net framework en la que se ejecuta la aplicación (es decir, es una aplicación web o una aplicación de intranet), entonces puedes probar algo como esto:

using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Internal;
using System.Reflection;

static class ConfigOverrideTest
{
  sealed class ConfigProxy:IInternalConfigSystem
  {
    readonly IInternalConfigSystem baseconf;

    public ConfigProxy(IInternalConfigSystem baseconf)
    {
      this.baseconf = baseconf;
    }

    object appsettings;
    public object GetSection(string configKey)
    {
      if(configKey == "appSettings" && this.appsettings != null) return this.appsettings;
      object o = baseconf.GetSection(configKey);
      if(configKey == "appSettings" && o is NameValueCollection)
      {
        // create a new collection because the underlying collection is read-only
        var cfg = new NameValueCollection((NameValueCollection)o);
        // add or replace your settings
        cfg["test"] = "Hello world";
        o = this.appsettings = cfg;
      }
      return o;
    }

    public void RefreshConfig(string sectionName)
    {
      if(sectionName == "appSettings") appsettings = null;
      baseconf.RefreshConfig(sectionName);
    }

    public bool SupportsUserConfig
    {
      get { return baseconf.SupportsUserConfig; }
    }
  }

  static void Main()
  {
    // initialize the ConfigurationManager
    object o = ConfigurationManager.AppSettings;
    // hack your proxy IInternalConfigSystem into the ConfigurationManager
    FieldInfo s_configSystem = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.Static | BindingFlags.NonPublic);
    s_configSystem.SetValue(null, new ConfigProxy((IInternalConfigSystem)s_configSystem.GetValue(null)));
    // test it
    Console.WriteLine(ConfigurationManager.AppSettings["test"] == "Hello world" ? "Success!" : "Failure!");
  }
}

Otros consejos

Independientemente de lo que haga, deberá agregar una capa de redirección. ConfigurationManager.AppSettings [" clave "] siempre buscará en el archivo de configuración. Puede crear un ConfigurationFromDatabaseManager pero esto resultará en el uso de una sintaxis de llamada diferente:

ConfigurationFromDatabaseManager.AppSettings["key"] instead of ConfigurationSettings["key"].

No estoy seguro de que pueda anularlo, pero puede probar el método Add de AppSettings para agregar la configuración de su base de datos cuando se inician las aplicaciones.

Intentaría escribir un inicio de aplicación y cargar la configuración de la base de datos al dominio de la aplicación. Así que la aplicación no sabe nada sobre cómo se genera la configuración. El uso de machiene.config conduce directamente a dll-hell 2.0.

Si puede guardar el archivo de configuración modificado en el disco, puede cargar un archivo de configuración alternativo en un dominio de aplicación diferente:

AppDomain.CreateDomain("second", null, new AppDomainSetup
{
    ConfigurationFile = options.ConfigPath,
}).DoCallBack(...);

Parece que hay una manera de hacer esto en .NET 3.5 configurando el atributo allowOverride en la sección de definición de ajustes de aplicación de machine.config. Esto le permite anular la sección completa en su propio archivo app.config y especificar un nuevo tipo para manejarlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top