C# - повторно инициализировать статический класс?

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

вот моя проблема; настройки хранятся в статическом классе и сами являются статическими свойствами только для чтения. Например

public static class Settings
{
 public static readonly setting1 = SettingmanagerClass.GetSetting("setting1");
 public static readonly setting2 = SettingmanagerClass.GetSetting("setting2");
 public static readonly setting3 = SettingmanagerClass.GetSetting("setting3");
}

теперь, например, через страница, которую я написал, Мы меняем значение для setting2 на" Happy Variable"; он сохраняет в БД просто отлично, но теперь мне нужно, чтобы он отражался в веб-приложении как новое значение. Поскольку это статическое свойство readonly статического класса, оно вызывается только тогда, когда приложение сначала подключается и не может быть установлено вручную.

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

Итак, в основном; есть ли способ повторно инициализировать статический класс после запуска веб-приложения? Мне просто нужно, чтобы он перезагрузил все свои свойства, как будто приложение было только что перестроено и запущено снова.

8 ответов


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

Edit: о, подождите-я не знал, что это веб-приложение. Вы могли бы программно отскок приложения:

System.Web.HttpRuntime.UnloadAppDomain

  ConstructorInfo constructor = typeof(Settings).GetConstructor(BindingFlags.Static | BindingFlags.NonPublic,null, new Type[0], null);
  constructor.Invoke(null, null);

вы можете использовать отражение:

var prop = typeof(Settings).GetField("setting1", BindingFlags.Static | 
                                                 BindingFlags.Public);
prop.SetValue(null, "Bar");
string currentValue = Settings.setting1; //Bar

единственный вариант приходит мне на ум, который требует много работы:

  1. создать другой AppDomain
  2. загрузить сборку в другой домен
  3. используйте Remoting для получения данных
  4. Если настройки изменились, выгрузите AppDomain и выполните шаги с 1 по 3 снова

Я бы использовал отражение

var info = typeof(Settings)
.GetField("Settings",BindingFlags.Static|BindingFlags.Public);
info.SetValue(null, "setting4");

Хм, вы хотите найти способ взломать классе? даже если он существует с отражением и чем-то подобным, это не лучший способ решить это

быстрый обходной путь я могу предложить создать вам собственные не только статические свойства, инициализировать статические переменные и использовать их везде

но лучше будет использовать кэш или хранилища приложений вместо статических переменных

надеюсь, что это помогает


старый поток я знаю, но одна вещь, которую я сделал, это создать инициализации метод (public static void), который устанавливает все переменные (все они являются общедоступными статическими). В этом методе выполняются вызовы базы данных и устанавливаются переменные класса. Затем в коде, в любое время, когда вы хотите обновить переменные (т. е. в любое время, когда вы вызываете SaveChanges ()), вы можете вызвать Class.Initialize() и все готово.

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


измените свои значения на свойства:

public static class Settings
{
 public static setting1
 {
   get { return SettingmanagerClass.GetSetting("setting1"); }
 }
 public static setting2
 {
   get { return SettingmanagerClass.GetSetting("setting2");
 }
 public static setting3
 {
   get { return SettingmanagerClass.GetSetting("setting3");
 }
}

кроме того, это не изменить сигнатуру кода.