2010-02-09 26 views
6

Estoy desarrollando una aplicación de blog compartida por organizaciones sin fines de lucro. Quiero que cada organización pueda cambiar su propia configuración de blog. Tomé un patrón singleton (de BlogEngine.net) y lo modifiqué. (Entiendo que ya no es un patrón único). He probado este enfoque y parece funcionar bien en un entorno de desarrollo. ¿Es este patrón una buena práctica? ¿Existen problemas que pueden surgir cuando se coloca en un entorno de producción?¿Es este patrón de singleton C# modificado una buena práctica?

public class UserBlogSettings 
    { 
    private UserBlogSettings() 
    { 
     Load(); 
    } 

    public static UserBlogSettings Instance 
    { 
      get 
      { 
       string cacheKey = "UserBlogSettings-" + HttpContext.Current.Session["userOrgName"].ToString(); 
       object cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 
       if (cacheItem == null) 
       { 
        cacheItem = new UserBlogSettings(); 
        HttpRuntime.Cache.Insert(cacheKey, cacheItem, null, DateTime.Now.AddMinutes(1), 
              Cache.NoSlidingExpiration); 
       } 
       return (UserBlogSettings) cacheItem; 
      } 
    } 
}  

(porciones de código se omiten por razones de brevedad.)

Gracias por cualquier ayuda, comentarios, etc.

Respuesta

5

Si su por sesión, almacenarlo en la sesión y no en la caché.

Además, estás upcasting y downcasting sin razón aquí:

object cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 

esto elimina los moldes que no sean necesarios

UserBlogSettings cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 
if (cacheItem == null) 
{ 
    cacheItem = new UserBlogSettings(); 
    HttpRuntime.Cache.Insert(cacheKey, cacheItem, null, 
         DateTime.Now.AddMinutes(1), 
         Cache.NoSlidingExpiration); 
} 
return cacheItem; 
+0

Es por la organización de usuarios (en contraposición a usuario) - por lo que la organización XYZ puede tener muchos usuarios en el sitio, al mismo tiempo ver sus blogs . –

+1

@geri Eso tiene más sentido. Aparte de la cuestión del reparto, no está mal. ¿Seguro que solo quieres guardarlo en caché por un minuto? Considere la duración del objeto al crearlo/insertarlo en el caché. – Will

+0

Gracias por la sugerencia de lanzamiento: el caché de un minuto es solo para desarrollo. ¿Qué pasa con la instancia estática? Cualquier problema con eso? –

0

Creo que tu es buena en general, pero yo sugeriría una actuación mejora si es necesario (lo sé ... no optimizar hasta que realmente lo necesite).

que probablemente aplicar esto con un método como este para obtener la configuración del objeto:

public static UserBlogSettings getSettings(string orgName, Cache cache) { 
    // do the same stuff here, except using the method parameters 
} 

La razón de esto es que HttpContext.Current y HttpRuntime.Cache tienen que pasar por algunos giros para llegar a los mangos la sesión actual y la memoria caché. Si llamas esto desde una página asp.net, ya tienes esas cosas a mano. Así que usa los que ya tienes en lugar de buscarlos de nuevo.

3

Es necesario utilizar el bloqueo para evitar posibles condiciones de carrera:

private static Object lock_Instance = new Object(); 
    public static UserBlogSettings Instance 
    { 
     get 
     { 
      string cacheKey = "UserBlogSettings-" + HttpContext.Current.Session["userOrgName"].ToString(); 
      UserBlogSettings cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 
      if (cacheItem == null) 
      { 
       lock (lock_Instance) 
       { 
        // need to check again in case another thread got in here too 
        cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 
        if (cacheItem == null) 
        { 
         cacheItem = new UserBlogSettings(); 
         HttpRuntime.Cache.Insert(cacheKey, cacheItem, null, 
          DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration); 
        } 
       } 
      } 
      return cacheItem; 
     } 
    } 
Cuestiones relacionadas