Есть ли способ переопределить ConfigurationManager.AppSettings? - PullRequest
22 голосов
/ 01 октября 2008

Я действительно хочу иметь возможность получить приложение, которое в настоящее время получает свои настройки, используя ConfigurationManager.AppSettings ["mysettingkey"] , чтобы фактически эти настройки исходили из централизованной базы данных вместо файл app.config. Я могу создать пользовательский раздел конфигурации для обработки такого рода вещей, но я действительно не хочу, чтобы другие разработчики в моей команде должны были менять свой код, чтобы использовать мой новый пользовательский раздел DbConfiguration. Я просто хочу, чтобы они могли вызывать AppSettings так, как они всегда, но загружать его из центральной базы данных.

Есть идеи?

Ответы [ 6 ]

25 голосов
/ 02 октября 2008

Если вы не возражаете против взлома фреймворка и можете разумно предположить версию .net, в которой работает приложение (т. Е. Это веб-приложение или приложение для интрасети), вы можете попробовать что-то вроде этого:

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!");
  }
}
1 голос
/ 02 октября 2008

Что бы вы ни делали, вам нужно будет добавить один слой перенаправления? ConfigurationManager.AppSettings ["ключ"] всегда будет искать в файле конфигурации. Вы можете создать ConfigurationFromDatabaseManager, но это приведет к использованию другого синтаксиса вызова:

ConfigurationFromDatabaseManager.AppSettings["key"] instead of ConfigurationSettings["key"].
0 голосов
/ 22 февраля 2017

Если вы можете сохранить измененный файл конфигурации на диск - вы можете загрузить альтернативный файл конфигурации в другой домен приложения:

AppDomain.CreateDomain("second", null, new AppDomainSetup
{
    ConfigurationFile = options.ConfigPath,
}).DoCallBack(...);
0 голосов
/ 12 августа 2009

Я бы попытался написать стартер приложения и загрузить настройки из базы данных в домен приложения. Так что приложение ничего не знает о том, как генерируется его конфигурация. Использование machiene.config ведет прямо в dll-hell 2.0.

0 голосов
/ 02 октября 2008

Похоже, есть способ сделать это в .NET 3.5, установив атрибут allowOverride в разделе определения appSettings файла machine.config. Это позволяет переопределить весь раздел в вашем собственном файле app.config и указать новый тип для его обработки.

0 голосов
/ 01 октября 2008

Я не уверен, что вы можете переопределить его, но вы можете попробовать метод Add из AppSettings, чтобы добавить настройки БД при запуске приложений.

...