2012-06-19 23 views
5

Acabo de participar en un clásico proyecto ASP.NET que contiene muchos valores de almacenamiento y lectura de la sesión y cadenas de consulta. Esto podría ser algo como lo siguiente:Siguiendo el principio DRY en ASP.NET

Session["someKey"]=someValue; 

Y en otro lugar del código se lee el valor de la sesión. Claramente, esto viola el principio DRY ya que tendrá la clave literal de la cadena distribuida por todo el código. Una forma de evitar esto podría ser almacenar todas las claves como constantes a las que se podría hacer referencia en cualquier lugar donde haya necesidad de leer y escribir en la sesión. Pero no estoy seguro de que sea la mejor forma de hacerlo. ¿Cómo recomendaría manejar mejor esto para no violar el principio DRY?

Respuesta

7

Crear una clase separada público donde puede definir sus constantes, por ejemplo

public class SessionVars 
{ 
    public const string SOME_KEY = "someKey"; 
    public const string SOME_OTHER_KEY = "someOtherKey"; 
} 

y luego cualquier parte del código se puede acceder a las variables de sesión como esto:

Session[SessionVars.SOME_KEY]=someValue; 

De esta manera se puede conseguir IntelliSence y otras campanas y silbatos.

+0

1 Este es el patrón tiendo a seguir - lo que realmente ayuda a eliminar esos errores tipográficos molestos. –

+1

No debe usar 'const' en este contexto. 'static readonly' es más apropiado (y seguro). – EkoostikMartin

+1

¿Cómo es eso aliviando el principio de No repetir? ¿Todavía está escribiendo el mismo liner en todas partes, solo está usando una variable constante en lugar de una cadena de instancia para la clave? – BlackSpy

2

Creo que estás leyendo demasiado en DRY. Me refiero más a las cosas que podrían envolverse en una función. Es decir. en lugar de repetir las mismas cinco líneas por todo el lugar, envuelve esas 5 líneas en una función y llama a la función donde sea que la necesites.

Lo que tiene como ejemplo es simplemente establecer un valor en un diccionario (el objeto de sesión en este caso), y esa es la forma más sencilla de almacenar y recuperar objetos en él.

+1

Me gustaría que nunca se hereda un proyecto lleno de magia * * encadena su necesidad de mantener ... –

0

Opcionalmente se puede colocar el acceso a este objeto de sesión en una página base y se envuelve en una propiedad:

class BasePage : Page 
{ 
    ... 
    public string MySessionObject 
    { 
     get 
     { 
     if(Session["myKey"] == null) 
      return string.Empty; 
     return Session["myKey"].ToString(); 
     } 
     set 
     { 
      Session["myKey"] = value; 
     } 
    } 
    ... 
} 

Aquí está repitiendo la cadena myKey pero se encapsula en la propiedad. Si quiere llegar al extremo de evitar esto, cree una constante con la tecla y reemplace la cadena.

1

No puedo recordar para la vida de mí, donde humildemente re-utilizados este código a partir, pero es bastante agradable:

using System; 
using System.Web; 

namespace Project.Web.UI.Domain 
{ 
    public abstract class SessionBase<T> where T : class, new() 
    { 
     private static readonly Object _padlock = new Object(); 

     private static string Key 
     { 
      get { return typeof(SessionBase<T>).FullName; } 
     } 

     public static T Current 
     { 
      get 
      { 
       var instance = HttpContext.Current.Session[Key] as T; 

       lock (SessionBase<T>._padlock) 
       { 
        if (instance == null) 
        { 
         HttpContext.Current.Session[Key] 
          = instance 
          = new T(); 
        } 
       } 
       return instance; 
      } 
     } 

     public static void Clear() 
     { 
      var instance = HttpContext.Current.Session[Key] as T; 
      if (instance != null) 
      { 
       lock (SessionBase<T>._padlock) 
       { 
        HttpContext.Current.Session[Key] = null; 
       } 
      } 
     } 
    } 
} 

La idea detrás de él dos veces. El tipo creado debe ser el único tipo que necesita. Básicamente es un envoltorio grande fuertemente tipado. Así que hay algún objeto que desea mantener la información que se extiende en:

public class MyClass 
{ 
    public MyClass() 

    public string Blah1 { get; set; } 
} 

A continuación, en el camino a ampliar MyClass y no quieren tener que recordar todos los valores clave, almacenarlos en AppSettings o variables en Const Clases estáticas Simplemente defina lo que desea almacenar:

public class MyClassSession : SessionBase<MyClass> 
{ 
} 

Y en cualquier lugar de su programa, simplemente use la clase.

// Any Asp.Net method (webforms or mvc) 
public void SetValueMethod() 
{ 
    MyClassSesssion.Current.Blah1 = "asdf"; 
} 

public string GetValueMethod() 
{ 
    return MyClassSession.Current.Blah1; 
} 
Cuestiones relacionadas