2010-02-15 17 views
37

Sono occupato nella conversione di un'applicazione Web in MVC e ho alcune informazioni salvate in variabili Application utilizzate su più tenant/account per rendere le cose un po 'più efficienti.asp.net MVC ha variabili applicative?

Mi rendo conto che MVC deve mantenere le cose il meno possibile stateless, Sesion State ha ovviamente senso avere ed esiste in MVC ma non vogliamo semplicemente convertire le variabili Application in Session come preferiremmo avere qualcosa di più globale e più sicuro. Le applicazioni MVC hanno variabili applicative? Ho visto alcuni esempi in cui viene utilizzato il caching? Questo è ormai standard e Quanto è robusto/sicuro rispetto allo stato di applicazione/sessione?

risposta

89

Sì, è possibile accedere alle variabili dell'applicazione da .NET MVC. Ecco come:

System.Web.HttpContext.Current.Application.Lock(); 
System.Web.HttpContext.Current.Application["Name"] = "Value"; 
System.Web.HttpContext.Current.Application.UnLock(); 
+2

Perché chiamare 'Lock' e' Unlock'? È necessario anche quando si legge un valore precedentemente impostato? – awe

+0

@awe aiuta a prevenire le condizioni di gara –

+0

@ZachM. Che razza di razza potrebbe accadere qui? È possibile creare 2 variabili di applicazione con lo stesso nome? Oltre a questo, non vedo che molto altro potrebbe entrare in una condizione di gara, e questo sarebbe qualcosa che mi aspetterei che l'operazione impostata fosse gestita internamente. – awe

2

Fare una classe statica?

+1

trovo classi statiche grande lavoro nel contesto di MVC, ma aiuta anche a ottenere lontano dall'idea stato di applicazione/sessione. –

+0

@jeremy tranne che lo stato della sessione viene aggiornato in modo specifico per l'utilizzo in MVC. Sosterrò sicuramente "scappare" per ridurre la quantità di stato memorizzato sul server, ma sicuramente ha ancora un posto nel framework. L'ambito di applicazione – Will

+1

e la classe statica sono cose molto diverse. Sebbene possano essere scambiati in alcune situazioni. – kervin

0

Hanno variabili applicative? Sì, MVC è un framework che si trova in cima al normale framework asp.net.

Vorrei tuttavia creare una classe statica che utilizza un archivio di cache come supporto.

+0

hi @ used2could puoi dirci i vantaggi dell'uso della classe statica con cache – Lakshay

7

Lo stato della sessione o la cache sono le scelte migliori. Sono mockable in MVC e sono progettati per memorizzare dati relativi a sessioni e ambiti applicativi.

Le classi statiche sembrano una scelta popolare qui. Tuttavia, le classi statiche creano dipendenze tra i tuoi tipi e rendono più duro il controllo delle versioni/test. È anche uno schema un po 'strano da utilizzare in un framework che è progettato per rompere a parte questo tipo di dipendenze. Ad esempio, il framework ASP.NET standard è pieno di statistiche e tipi sigillati. Questi sono tutti sostituiti con istanze finte.

"Sicuro" è un po 'poco chiaro in questo contesto. Esattamente cosa intendi con "sicuro?"

+2

Ovviamente per il disaccoppiamento ottimale, testare eccetera uno dovrebbe archiviarli in una classe ordinaria e mettere un'istanza di quella classe in un contenitore IoC. – svinto

+1

@svinto che tutto dipende dal resto del progetto. IOC non è configurazione. È possibile configurare per IOC ma si tratta più del tipo da utilizzare in questa situazione, non del colore da utilizzare sullo sfondo dell'intestazione, ad esempio. – Will

+0

Votato! Le classi statiche hanno molti degli stessi problemi delle variabili globali e dei grandi S Singletons. Sono strettamente accoppiati, difficili da testare e possono avere problemi di concorrenza. Se usi classi statiche dovresti rendere tutte le proprietà in sola lettura !! Meglio memorizzare le tue variabili in un file di dati (XML, JSON, YAML) o in un database e poi metterle nella cache. Questo ha anche il vantaggio di farti cambiare la configurazione senza ricompilare. IoC potrebbe essere utile se pensi di poter cambiare l'origine dei dati e vuoi essere in grado di passare da una classe all'altra per caricare i dati nella cache. –

4

Ho implementato qualcosa come di seguito come estensione per variabile di stato globale. Ho messo le cose come il titolo del sito, Servizio Endpoint, ruoli autorizzati

public static class ApplicationStateExtension 
{ 
    public static T GetSetApplicationState<T>(this HttpApplicationState appState, string objectName, object objectValue = null, int syncCheckMinutes = 0) 
    { 
     T retVal = default(T); 
     appState.Lock(); 
     if (appState[objectName + "LastSync"] == null || DateTime.Now.Subtract(((DateTime)appState[objectName + "LastSync"])).TotalMinutes >= syncCheckMinutes) 
     { 
      appState[objectName + "LastSync"] = DateTime.Now; 

      if (objectValue != null) 
       appState[objectName] = objectValue; 
     } 
     if (appState[objectName] != null) 
      retVal = (T)appState[objectName]; 
     appState.UnLock(); 
     return retVal; 
    } 
    public static object GetSetApplicationState(this HttpApplicationState appState, string objectName, object objectValue = null, int syncCheckMinutes = 0) 
    { 
     object retVal = null; 
     appState.Lock(); 
     if (appState[objectName + "LastSync"] == null || DateTime.Now.Subtract(((DateTime)appState[objectName + "LastSync"])).TotalMinutes >= syncCheckMinutes) 
     { 
      appState[objectName + "LastSync"] = DateTime.Now; 

      if (objectValue != null) 
       appState[objectName] = objectValue; 
     } 
     if (appState[objectName] != null) 
      retVal = appState[objectName]; 
     appState.UnLock(); 
     return retVal; 
    } 
    public static void SetApplicationState(this HttpApplicationState appState, string objectName, object objectValue, int syncCheckMinutes = 0) 
    { 
     appState.Lock(); 
     if (appState[objectName + "LastSync"] == null || DateTime.Now.Subtract(((DateTime)appState[objectName + "LastSync"])).TotalMinutes >= syncCheckMinutes) 
     { 
      appState[objectName + "LastSync"] = DateTime.Now; 
      appState[objectName] = objectValue; 
     } 
     appState.UnLock(); 
    } 
    public static object GetApplicationState(this HttpApplicationState appState, string objectName) 
    { 
     object retVal = null; 
     appState.Lock(); 
     if (appState[objectName] != null) 
      retVal = appState[objectName]; 
     appState.UnLock(); 
     return retVal; 
    } 
    public static T GetApplicationState<T>(this HttpApplicationState appState, string objectName) 
    { 
     T retVal = default(T); 
     appState.Lock(); 
     if (appState[objectName] != null) 
      retVal = (T)appState[objectName]; 
     appState.UnLock(); 
     return retVal; 
    } 
} 

Così posso metterli da Global.asax.cs qualcosa di simile

Application.SetApplicationState("UISiteTitle",paramHelper.GetUIConfigXML<XMLParams.UISiteOptions>("UISiteOptions") 
       .SiteOptionCollection.Where(v => v.name.Equals("title", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault().value);); 

o

var uiPermissions = Application.GetSetApplicationState<XMLParams.UIPermissions>("UIPermissions", paramHelper.GetUIConfigXML<XMLParams.UIPermissions>("UIPermissions"), 30); 
+0

Qual è il punto di "LastSync" in questo? È necessario per l'uso generico? – Fandango68

0

Puoi dichiarare le variabili dell'applicazione in Application_Start in questo modo:

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    RouteConfig.RegisterRoutes(RouteTable.Routes); 

    var e = "Hello"; 
    Application["value"] = e; 
} 

Per accedere a questa scrittura sul controller:

string appVar = HttpContext.Application["value"] as string;