Переопределить WebConfigurationManager.AppSettings ["SomeProperty"] динамически во время выполнения - PullRequest
0 голосов
/ 27 октября 2011

У меня есть такой код:

// can't make any changes at that class
class MyClass
{
    void SomeMethod()
    {
        // some code ...

        var someVar = WebConfigurationManager.AppSettings["SomeProperty"];

        // some code ...
    }
}

Я не могу изменить этот код, но мне нужно, чтобы WebConfigurationManager.AppSettings ["SomeProperty"] возвращал разные значения в зависимости от некоторых внешних условий (например, в зависимости от роли пользователя). Поэтому я ищу способ переопределить доступ к этому свойству. В этом методе переопределения я бы проверил роль пользователя и вернуть соответствующее значение.

Есть ли способ сделать это?

Я нашел этот вопрос: Есть ли способ переопределить ConfigurationManager.AppSettings? но мне кажется, что он мне не подходит, потому что здесь значение WebConfigurationManager.AppSettings ["SomeProperty"] устанавливается один раз, когда приложение начинается. И мне нужно сделать это динамически.

Ответы [ 5 ]

1 голос
/ 15 января 2016

В MVC, чтобы упростить тестирование и макетирование, я склонен использовать настраиваемый объект для всех общих классов, таких как Request, Session и ConfigManager, на которые ссылаются через интерфейсы. Очевидно, вам не нужно реализовывать классы с нуля, поэтому ваша реализация может быть оболочкой, которая фактически использует класс .net под капотом, но которая также дает возможность вставить некоторую пользовательскую логику в середине, как в вашей случай.

Следовательно, вы можете создать оболочку webconfigurationManager с помощью метода, подобного GetAppConfig (ключ), содержащего вашу собственную логику. Играть с концепцией внедрения зависимостей тогда достаточно просто, если этот класс доступен там, где он вам нужен.

Поэтому приведем простой пример:

//this will be injected
public MyControllerCtor(IConfig cfg)

public interface IConfig
{
   string GetAppConfig(string key);
}

public class myConfig:IConfig
{
   public string GetAppConfig(string key)
   {    
      //your logic
      var someVar = WebConfigurationManager.AppSettings["SomeProperty"];
      //your logic

      return yourCustomAppSetting;
   }
}

Большим преимуществом этого подхода является то, что если вы хотите сохранить свою конфигурацию в базе данных или службе и изменить свой код, вам просто нужно изменить реализацию интерфейса и внедрить новый экземпляр.

0 голосов
/ 28 октября 2011

Нет, конечно, нет.

Если вы не можете изменить класс, то вы не можете изменить поведение. Нет общей причины, по которой Microsoft поместила бы возможность переопределения внутри WebApplicationManager. Обычно ожидается, что кто-то сможет изменить класс или правильно спроектировать его, чтобы он мог быть переопределен правильным образом.

0 голосов
/ 27 октября 2011

Похоже, вам нужно немного поработать после получения значения из web.config. Если логика изменяет само значение, вы всегда можете вместо этого сохранить строку формата в файле web.config.

Вот пример использования настройки строки подключения. Я использую строку формата для заполнения имени сервера во время выполнения:

<add name="sqlconnection" connectionString="Server={0}\SQLEXPRESS;Database=xxx;Trusted_Connection=True;"/>    

И тогда я использую эту логику:

string connect = ConfigurationManager.ConnectionStrings["sqlconnection"].ConnectionString;
if (!String.IsNullOrEmpty(connect))
{
    //check to see if the connection string needs to be set at runtime
    if (connect.Contains("{0}"))
        connect = String.Format(connect, HttpContext.Current.Server.MachineName);
}

return connect;

РЕДАКТИРОВАТЬ: Если вы не можете редактировать класс напрямую, я бы рассмотрел создание частичного класса для реализации этого.

0 голосов
/ 28 октября 2011

Если вы не можете изменить код, который читает AppSettings, то нет способа сделать то, что вы хотите.WebConfigurationManager не может быть подключен или заменен извне.

Вам придется изменить код.

0 голосов
/ 27 октября 2011

Если вы внесете прямые изменения в Web.config, они вступят в силу только при следующем запросе, и, как я понимаю, это нежелательный эффект.

Вы не можете напрямую влиять на WebConfigurationManager.AppSettings ["SomeProperty"], и это желаемое поведение, так как AppSettings как конфигурации являются чем-то статичным.

Чтобы получить эффект, близкий к тому, что вы хотите, я бы предложил вам использовать коллекцию HttpContext.Current.Items, в которой вы инициализируете в Application_BeginRequest определенное значение, если выполняются условия или по умолчанию WebConfigurationManager.AppSettings [ "SomeProperty"] в противном случае.
Чем вместо доступа к WebConfigurationManager.AppSettings ["SomeProperty"] вы будете обращаться к HttpContext.Current.Items ["SomeProperty"].

...