5

我最近刚刚参与了一个经典的 ASP.NET 项目,该项目包含大量存储和读取会话和查询字符串中的值。这可能类似于以下内容:

Session["someKey"]=someValue;

在代码的其他地方读取会话中的值。显然,这违反了 DRY 原则,因为您将在整个代码中散布文字字符串键。避免这种情况的一种方法是将所有键存储为可以在需要读取和写入会话的任何地方引用的常量。但我不确定这是最好的方法。你会建议我如何最好地处理这个问题,这样我就不会违反 DRY 原则?

4

4 回答 4

7

创建一个单独的公共类,您可以在其中定义常量,例如

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

然后在代码中的任何地方都可以访问会话变量,如下所示:

Session[SessionVars.SOME_KEY]=someValue;

通过这种方式,您可以获得 IntelliSence 和其他花里胡哨的功能。

于 2012-06-19T21:51:00.700 回答
2

我认为您对 DRY 的了解太多了。我更多地涉及可以包含在函数中的东西。即,不要在所有地方重复相同的五行,而是将这 5 行包装在一个函数中,并在需要的任何地方调用该函数。

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

于 2012-06-19T21:49:39.780 回答
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 或静态类中的 Const 变量中。您只需定义要存储的内容:

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;
}
于 2012-06-19T21:58:49.700 回答
0

或者,您可以将此会话对象的访问权限放在一个基本页面中并将其包装在一个属性中:

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

在这里,您正在重复myKey字符串,但它被封装到属性中。如果您想尽量避免这种情况,请使用键创建一个常量并替换字符串。

于 2012-06-19T21:55:36.307 回答