2012-04-23 20 views
6

Tengo una clase en una aplicación web en la que estoy trabajando que guarda la configuración del cliente. Para algunos antecedentes, no soy dueño de esta clase y cambiarla no es una opción. Recientemente agregamos un poco de lógica para almacenar la configuración en una base de datos, y me asignaron la tarea de crear una página para editarlos, lo suficiente.C# - ¿Reiniciar la clase estática?

Aquí está mi problema; las configuraciones se mantienen en una clase estática, y son propiedades estáticas de solo lectura. Por ejemplo

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

Ahora, por ejemplo, a través de la página que escribí, cambiamos el valor para setting2 a "Happy Variable"; se guarda bien en el DB, pero ahora necesito que se refleje en la aplicación web como el nuevo valor. Como es una propiedad de solo lectura estática de una clase estática, solo se llama cuando la aplicación se conecta por primera vez y no se puede configurar manualmente.

Solo para reiterar, no poseo la clase original, por lo que "simplemente haga que las propiedades sean grabables" no es (actualmente) una opción válida. Normalmente me gustaría hablar de esto con mi jefe y él haría una llamada de juicio y posiblemente me permita modificar la otra clase, pero no estoy en condiciones de hacer esa llamada y él estará fuera de la oficina por una semana.

Así que básicamente; ¿Hay alguna manera de reiniciar una clase estática una vez que una aplicación web ha comenzado a ejecutarse? Solo necesito que vuelva a cargar todas sus propiedades como si la aplicación acabara de reconstruirse y se iniciara de nuevo.

+0

Puede cambiarlo con reflexión o reciclar el proceso. [Aquí hay un hilo] (http://stackoverflow.com/questions/934930/can-i-change-a-private-readonly-field-inc-c-sharp-using-reflection) sobre cómo hacer la reflexión: – zeal

+0

Solo una nota al margen: ¿sabe que todas las configuraciones (fe de web.config) están en caché de todos modos? –

+0

¿Es posible reiniciar su IIS? [Iniciar o detener un grupo de aplicaciones (IIS 7)] (http://technet.microsoft.com/en-us/library/cc732742 (v = WS.10) .aspx) – Steve

Respuesta

2

Si el código anterior es representativo de la situación en la que se encuentra, no podrá reiniciar el código a menos que haga algo particularmente raro con la reflexión (esto no se recomienda).

Editar: Oh, espera - No me di cuenta de que esto era una aplicación web. Usted podría programación bounce the application:

System.Web.HttpRuntime.UnloadAppDomain 
+0

Esto podría ser peligroso, sin embargo, si otros usuarios están en el sistema y la sesión se pierde debido a un rebote. – tsells

+0

@tells - absolutamente. – RQDQ

+0

De hecho acabo de probar esto con el escenario que expuse en la publicación original y funcionó; ninguna pérdida de sesión en absoluto, solo la configuración recargada. Perfecto. Lo he probado varias veces para asegurarme de que no estoy solo entusiasmado por un éxito percibido, pero por lo que puedo ver, ¡esto es pura victoria, gracias! – ddietle

-2

Cambiar los valores de propiedades:

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

Además, esto no cambia la firma de su código.

+3

El OP indicó que las ediciones de código en la clase no eran posibles. –

+0

Él dijo, "no es (actualmente) una opción válida." La forma en que he codificado mantiene los campos 'readonly' (si se trata de un requisito de Cliente o de Especificación). Algo tiene que cambiar para proporcionar esto. – jp2code

+2

Solo para aclarar, no perdoné. De cualquier manera, semántica sobre las palabras exactas. Si el OP * podría * editar el código, las posibilidades son muy buenas, esta pregunta no existiría. –

1

La única opción que viene a la mente que es requiere mucho trabajo:

  1. Cree otro dominio de aplicación
  2. ensamblaje de carga en el otro dominio
  3. Uso Remoting para obtener los datos
  4. Si configuración modificada, descargue AppDomain y realice los pasos 1 a 3 nuevamente
0

Hmm, desea encontrar una forma de hackear la clase ?incluso si es que existe con la reflexión y algo por el estilo, no es una buena manera de resolver este

solución rápida que puedo sugerir para crear que no es dueño de sólo lectura propiedades estáticas, inicializar con que las variables estáticas y los utilizan en todas partes

pero será mejor utilizar la caché o aplicación almacena en lugar de las variables estáticas

esperanza esto ayuda

+0

El uso de la sesión no es un lugar apropiado para los datos que tienen como ámbito toda la aplicación. Además, el OP declaró que no posee el código ofensivo. – RQDQ

+0

Editado, seguro @RQDQ, la aplicación o el caché será mejor –

4

se podría utilizar la reflexión:

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

me gustaría utilizar la reflexión

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

Esto realmente funciona. Dios odio la reflexión a veces lol –

+0

Gracias. Probé con la clase OPs para asegurarme de que se publicó :) –

+0

Me cansé de esto, y trabajé absolutamente, pero la aplicación web por algún extraño motivo continuó cargando los valores originales en las páginas a pesar del depurador que muestra el valor actualizado. Muy raro, y aunque no lo use esta vez, me aferraré a ese, es genial, incluso si es por razones puramente académicas (para mí) en este momento. – ddietle

0

Antiguo Lo sé, pero una cosa que he hecho es crear un Inicializar método (public static void) que establece todas las variables (que' re todo público estático). En ese método, se realizan las llamadas a la base de datos y se establecen las variables de la clase. Luego, en el código, cada vez que desee actualizar las variables (es decir, cada vez que llame a SaveChanges()), puede llamar a Class.Initialize() y listo.

Lo uso para el almacenamiento en caché de listas comunes de información de búsqueda que pueden cambiar, y debemos mantenerlo sincronizado para cuando la base de datos se actualice desde la aplicación.