Есть ли способ переопределить ConfigurationManager. AppSettings?

Отличная работа на MCVE. Я смог призвать SampleMethod; Оказывается, в этом нет ничего особенного, и это, вероятно, менее сложно, чем вы себе представляли.

В вашем примере, объект, который вы получаете, howToCastThis, имеет тип, который уже закрыт. Пока вы начинаете с типа этого экземпляра, вам не нужно использовать MakeGenericMethod.

Допустим, у вас есть экземпляр объекта, compileTimeTypeUnknownInstance, для параметра, который вы хотите передать SampleMethod. Поскольку System.IO.TextReader является абстрактным, compileTimeTypeUnknownInstance должен быть конкретного, TextReader -производного типа. При соблюдении этих условий выполняются следующие работы:

var sampleMethod = howToCastThis.GetType().GetMethods()
    .Single(mi => mi.Name == "SampleMethod");

sampleMethod.Invoke(howToCastThis, new object[] { compileTimeTypeUnknownInstance });

SampleMethod сообщает, что T относится к типу System.Text.TextReader.

Опять же, howToCastThis имеет тип с близким построением, поэтому, как и метод, который вы хотите.

Примечание. Хотя это и не тот случай, метод закрытого типа может вводить дополнительные аргументы типа, поэтому вам все равно придется вызывать MakeGenericMethod для закрытия метода в этом случае.

Теперь, если бы я попытался перевести это в вашу ситуацию, я думаю, это выглядело бы примерно так:

var predictMethod = predictionEngine.GetType().GetMethods()
    .Single(mi => mi.Name == "Predict");

float prediction = (float)predictMethod.Invoke(predictionEngine, new object[] { inputValue });

Я не уверен насчет синтаксиса в вашем вызове псевдокода для Predict. Я предположил, что inputValue был единственным параметром, а genericInputClass был только там, чтобы указать, что это был аргумент типа в типе с закрытым построением. Если это неверно, вам нужно выяснить, что на самом деле входит в этот аргумент object[].

22
задан skb 1 October 2008 в 17:36
поделиться

5 ответов

Если Вы не возражаете бездельничать платформа, и можно обоснованно принять .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!");
  }
}
25
ответ дан 29 November 2019 в 05:32
поделиться

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

ConfigurationFromDatabaseManager.AppSettings["key"] instead of ConfigurationSettings["key"].
1
ответ дан 29 November 2019 в 05:32
поделиться

Я не уверен, что можно переопределить его, но можно попробовать Добавить метод AppSettings для добавления настроек DB, когда приложения запускаются.

0
ответ дан 29 November 2019 в 05:32
поделиться

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

-1
ответ дан 29 November 2019 в 05:32
поделиться

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

0
ответ дан 29 November 2019 в 05:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: