2012-04-23 32 views
6

Mam zajęcia w aplikacji internetowej, nad którą pracuję, która zawiera ustawienia klienta. Na pewnym tle nie jestem właścicielem tej klasy, a jej zmiana nie jest opcją. Niedawno dodaliśmy trochę logiki do przechowywania ustawień w bazie danych, a zadanie polegało na utworzeniu strony, która je edytowała, wystarczająco dobrze.C# - Ponownie zainicjować klasę statyczną?

Oto mój problem; ustawienia są przechowywane w klasie statycznej i same są statycznymi właściwościami tylko do odczytu. Na przykład:

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"); 
} 

Teraz, na przykład, przez stronę, którą napisałem, zmieniamy wartość ustawienia2 na "Happy Variable"; zapisuje się do bazy danych w porządku, ale teraz potrzebuję, aby znalazła się w aplikacji internetowej jako nowa wartość. Ponieważ jest to statyczna właściwość readonly klasy statycznej, jest ona wywoływana tylko wtedy, gdy aplikacja jest najpierw podłączona i nie może być ustawiona ręcznie.

Powtarzam tylko, nie jestem właścicielem oryginalnej klasy, więc "po prostu ustaw właściwości do zapisu" nie jest (obecnie) prawidłową opcją. Zwykle po prostu rozmawiałbym o tym z moim szefem, a on wygłosiłby wezwanie do sądu i ewentualnie pozwoliłby mi zmodyfikować drugą klasę, ale nie jestem w stanie wykonać tego połączenia, a on jest poza biurem przez cały tydzień.

W zasadzie; czy istnieje sposób na ponowne zainicjowanie klasy statycznej po uruchomieniu aplikacji internetowej? Potrzebuję go do przeładowania wszystkich jego właściwości, tak jakby aplikacja została ponownie przebudowana i uruchomiona ponownie.

+0

Możesz to zmienić poprzez odbicie lub recykling procesu. [Tutaj jest wątek] (http://stackoverflow.com/questions/934930/can-i-change-a-private-readonly-field-in-c-sharp-using-reflection) o tym, jak zrobić refleksję: – zeal

+0

Tylko jedna uwaga: Wiesz, że wszystkie ustawienia (np. Z web.config) są w pamięci podręcznej i tak? –

+0

Czy można ponownie uruchomić usługi IIS? [Uruchom lub zatrzymaj pulę aplikacji (IIS 7)] (http://technet.microsoft.com/en-us/library/cc732742 (v = WS.10) .aspx) – Steve

Odpowiedz

2

Jeśli powyższy kod jest reprezentatywny dla sytuacji, w której się znajdujesz, nie będzie można ponownie zainicjować kodu, chyba że zrobisz coś szczególnie odrażającego z powodu refleksji (nie jest to zalecane w sposób zalecany).

Edytuj: Oh wait - Nie zdawałem sobie sprawy, że to aplikacja internetowa. Można by programowo bounce the application:

System.Web.HttpRuntime.UnloadAppDomain 
+0

Może to być niebezpieczne, jeśli inni użytkownicy są w systemie, a sesja zostanie utracona z powodu odrzucenia. – tsells

+0

@tells - absolutnie. – RQDQ

+0

Właśnie przetestowałem to w porównaniu ze scenariuszem, który przedstawiłem w oryginalnym poście i zadziałało; bez utraty sesji, tylko ustawienia przeładowane. Idealny. Przetestowałem to kilka razy, aby upewnić się, że nie jestem po prostu podekscytowany postrzeganym sukcesem, ale z tego, co widzę, to jest czysta wygrana, dziękuję! – ddietle

-2

Zmień swoje wartości do właściwości:

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"); 
} 
} 

Również nie zmienia podpis kodzie.

+3

PO oświadczył, że edytowanie kodu w klasie nie było możliwe. –

+0

Stwierdził, że "nie jest (obecnie) ważną opcją." Sposób, w jaki kodowałem utrzymuje pola 'readonly' (jeśli jest to wymóg klienta lub specyfikacji). Coś musi się zmienić, aby to zapewnić. – jp2code

+2

Aby wyjaśnić, nie upadłem. Tak czy inaczej, semantyka na dokładnych słowach. Jeśli OP * może * edytować kod, szanse są bardzo dobre, to pytanie nie istnieje. –

1

Jedynym rozwiązaniem przychodzi do mojego umysłu, który jest wymaga dużo pracy:

  1. Tworzenie innego AppDomain
  2. montaż obciążenia w innej domenie
  3. Zastosowanie Remoting aby uzyskać dane
  4. Jeśli ustawienia zostały zmienione, zwolnij AppDomain i wykonaj ponownie kroki od 1 do 3
0

Hmm, chcesz znaleźć sposób na zhackowanie klasy ?nawet jeśli istnieje z refleksji i coś takiego, to nie jest dobry sposób, aby rozwiązać ten

Szybkie obejście mogę zaproponować, aby utworzyć nie właścicielem tylko do odczytu właściwości statyczne, zainicjować z tym zmiennych statycznych i używać ich wszędzie

ale będzie lepiej, aby zamiast wykorzystywać Cache lub aplikacja przechowuje zmiennych statycznych

nadzieję, że to pomaga

+0

Korzystanie z sesji nie jest odpowiednim miejscem dla danych obejmujących całą aplikację. Ponadto OP stwierdził, że nie jest właścicielem naruszającego kod. – RQDQ

+0

Edytowane, pewny @RQDQ, Application lub cache będą lepsze –

4

można użyć refleksji:

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

użyłbym odbicie

var info = typeof(Settings) 
.GetField("Settings",BindingFlags.Static|BindingFlags.Public); 
info.SetValue(null, "setting4"); 
12
ConstructorInfo constructor = typeof(Settings).GetConstructor(BindingFlags.Static | BindingFlags.NonPublic,null, new Type[0], null); 
    constructor.Invoke(null, null); 
+0

To faktycznie działa. Bóg nienawidzę refleksji czasami lol –

+0

Dzięki. Przetestowałem z klasą OPs, aby się upewnić, że nie napisałem :) –

+0

Zmęczony tym i pracowałem absolutnie, ale aplikacja internetowa z jakiegoś dziwnego powodu nadal ładowała oryginalne wartości na stronach pomimo debuggera pokazującego zaktualizowaną wartość. Bardzo dziwne, i chociaż tym razem nie skorzystałem z tego, będę to trzymał, to jest świetne, nawet jeśli jest to wyłącznie ze względów akademickich (dla mnie) właśnie teraz. – ddietle

0

Stary wątek wiem, ale jedno mam zrobić jest stworzenie Initialize metody (statyczny public void), który ustawia wszystkie zmienne (oni ponownie wszystkie publiczne statyczne). W tej metodzie wywoływane są bazy danych i ustawione są zmienne tej klasy. Następnie w kodzie, w dowolnym momencie, gdy chcesz odświeżyć zmienne (tj. W dowolnym momencie, gdy wywołasz SaveChanges()), możesz wywołać Class.Initialize() i gotowe.

Używam tego do buforowania wspólnych list informacji wyszukiwania, które mogą ulec zmianie, i musimy zachować synchronizację, gdy baza danych jest aktualizowana z aplikacji.

Powiązane problemy