2012-06-19 24 views
5

我刚刚参与了一个经典的ASP.NET项目,其中包含大量来自会话和查询字符串的存储和读取值。这可能看起来像下面这样:遵循ASP.NET中的DRY原理

Session["someKey"]=someValue; 

而在代码中的其他位置读取会话中的值。很明显,这违反了DRY原则,因为您将字面字符串键遍布整个代码。避免这种情况的一种方法是将所有密钥存储为常量,并在需要读取和写入会话的任何地方引用它们。但我不确定这是做到这一点的最佳方式。你会如何建议我最好处​​理这个问题,以免违反DRY原则?

回答

7

创建一个单独的公共类,你可以定义常量,如

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

,然后在你的代码的任何地方,你可以像这样访问会话变量:

Session[SessionVars.SOME_KEY]=someValue; 

这样你就可以得到IntelliSence和其他花里胡哨的。

+0

+1这是我倾向于遵循的模式 - 它确实有助于消除这些讨厌错字错误。 –

+1

你不应该在这种情况下使用'const'。 “静态只读”更合适(和安全)。 – EkoostikMartin

+1

这是如何缓解不重复自己的原则?你仍然在编写同一个班轮,你只是使用一个常量变量而不是实例字符串作为键? – BlackSpy

2

我认为你的阅读过于干燥。我更多地关注可能包含在函数中的东西。即而不是在所有地方重复相同的五行,将这五行包装在一个函数中,并在需要的地方调用函数。

作为示例,您只需在字典(本例中为会话对象)中设置一个值,这是在其中存储和检索对象的最简单方法。

+1

我希望你永远不会继承一个项目充满魔力*弦乐器*您必须保持... –

0

可选,你可以在碱页面访问这个会话对象和属性把它包:

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

在这里,你都在重复着myKey字符串,但它被封装到属性。如果你想要避免这种情况的极端,用键创建一个常量并替换字符串。

1

我不记得我的一生中,我虚心重新定意从这个代码,但它是相当不错的:

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

它背后的理念二折。创建的类型应该是您需要的唯一类型。它基本上是一个大的强类型包装。所以,你有一些对象,你要保持在扩展信息:

public class MyClass 
{ 
    public MyClass() 

    public string Blah1 { get; set; } 
} 

然后在路上,你延伸MyClass,你不想记住所有的核心价值观,将它们存储在的AppSettings或常变量静态类。您只需定义要存储什么:

public class MyClassSession : SessionBase<MyClass> 
{ 
} 

,随时随地在你的程序,你只需使用类。

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

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