C# 会话与单例模式

C# 会话与单例模式,c#,asp.net,asp.net-mvc,design-patterns,C#,Asp.net,Asp.net Mvc,Design Patterns,我有一个web应用程序,我想从数据库中提取用户设置并存储它们以供全局访问。将数据存储在单例或会话对象中更有意义吗?这两者有什么区别 将数据存储为对象引用还是将其分解为值类型对象(整数和字符串)更好。这就是它的目的。会话存储在全局缓存(基本上是一个单例)中,由会话id键控。这样,您只获得感兴趣的会话的数据。使用单例基本上就是复制全局缓存,您必须重新发明机制,独立地检索每个会话的数据 继续并存储该对象。让会话担心将其序列化为可以恢复的内容。不过,要注意你在课程中的内容。您不想在那里存储太多数据,否则

我有一个web应用程序,我想从数据库中提取用户设置并存储它们以供全局访问。将数据存储在单例或会话对象中更有意义吗?这两者有什么区别


将数据存储为对象引用还是将其分解为值类型对象(整数和字符串)更好。这就是它的目的。会话存储在全局缓存(基本上是一个单例)中,由会话id键控。这样,您只获得感兴趣的会话的数据。使用单例基本上就是复制全局缓存,您必须重新发明机制,独立地检索每个会话的数据


继续并存储该对象。让会话担心将其序列化为可以恢复的内容。不过,要注意你在课程中的内容。您不想在那里存储太多数据,否则会占用大量内存(假设内存缓存)。

如果这些设置将用于站点的所有用户,请将它们放在单例缓存或应用程序缓存中。如果它们特定于每个用户,请将它们置于会话中


在添加到应用程序或会话缓存时使用对象引用-我相信值类型将被装箱,以便它们看起来像缓存中的对象。如果您使用单例,它可以是任何一种方式。

会话对象,当然

单例存在于流程级别。这意味着,如果在任何给定时刻有20个用户访问您的站点,那么他们使用的是同一个单例对象。如果您不经常进行web开发,就很难习惯这个概念


会话存在于用户级别。这意味着您可以按用户存储数据,而不是按进程存储数据。

有时我喜欢下面的方法。它解决了魔术字符串和未设置会话变量的问题。它还在会话级别而不是应用程序级别运行单例

public static SessionHandler GetInstance()
    {
        if (HttpContext.Current.Session["SessionHandler"] == null)
        {
            HttpContext.Current.Session["SessionHandler"] = new SessionHandler();
        }
        return (SessionHandler)HttpContext.Current.Session["SessionHandler"];
    }

那就把它当作一个普通的单体来使用吧。输入您需要的变量。

这是从一个旧文档中获取的,但它仍然非常有效,并且非常有效。。。我将把链接内容放在这里,特别是因为它是一个可能会消失的旧链接

背景

ASP.Net中的会话对象可用于存储特定于站点单个用户的信息。会话由一个键名编制索引,如果以这种方式直接使用会话,则会产生大量单独的会话名。另一种方法是创建一个singleton对象来对相关项进行分组,并使用给定的键名存储该对象。“singleton”是一种常见的设计模式,它指定如何确保在任何时候都只存在一个类的单个实例

单例会话对象的优势

  • 为组织目的对会话项进行分组
  • 特别适用于瞬态过程中的一系列页面,如网站注册。进程完成后,可以从会话中清除对象,以便回收内存(更好地使用服务器) (资源)
  • 对会话信息更改的影响分析要容易得多
  • 识别站点中误用信息的区域(比仅使用变量名称来确定是否适合使用要清楚得多)
  • 一旦访问对象,属性名称和类型的Intellisense
单例会话对象的缺点

更难看到会话中单个项目的数量 ASP.Net跟踪结果不显示对象内的值 使用进程外会话状态存储时性能下降(影响序列化)

实施

实现的第一步是创建一个类文件,该类文件表示应一起存储在单个对象中的项的逻辑分组。下面是演示该技术的示例类:

public class singleton
{
  //Name that will be used as key for Session object
  private const string SESSION_SINGLETON = "SINGLETON";

  //Variables to store the data (used to be individual
  // session key/value pairs)
  string lastName = "";
  string firstName = "";

  public string LastName
  {
    get
    {
      return lastName;
    }
    set
    {
      lastName = value;
    }
  }

  public string FirstName
  {
    get
    {
      return firstName;
    }
    set
    {
      firstName = value;
    }
  }

  //Private constructor so cannot create an instance
  // without using the correct method.  This is 
  // this is critical to properly implementing
  // as a singleton object, objects of this
  // class cannot be created from outside this
  // class
  private singleton()
  {
  }

  // Create as a static method so this can be called using
  // just the class name (no object instance is required).
  // It simplifies other code because it will always return
  // the single instance of this class, either newly created
  // or from the session
  public static singleton GetCurrentSingleton()
  {
    singleton oSingleton;

    if (null == System.Web.HttpContext.Current.Session[SESSION_SINGLETON])
    {
      //No current session object exists, use private constructor to 
      // create an instance, place it into the session
      oSingleton = new singleton();
      System.Web.HttpContext.Current.Session[SESSION_SINGLETON] = oSingleton;
    }
    else
    {
      //Retrieve the already instance that was already created
      oSingleton = (singleton)System.Web.HttpContext.Current.Session[SESSION_SINGLETON];
    }

    //Return the single instance of this class that was stored in the session
    return oSingleton;
  }
}
要使用此对象的页面只需执行以下操作:

singleton oSingleton = singleton.GetCurrentSingleton();
oSingleton.FirstName = "Robert";
oSingleton.LastName = "Boedigheimer";
通常,这种技术将在给定的类中存储更多的变量,或者用于执行一个过程的一系列网页。在网站上的进程中使用它的另一个优点是,只需删除对singleton对象的引用,就可以清除会话变量所需的所有内存。该类可以实现一个方法,客户端可以使用该方法清除引用,当类提供清理方法时,可以将其命名为Dispose(),以遵循典型的.Net模式:

public static void Dispose()
{
    //Cleanup this object so that GC can reclaim space
    System.Web.HttpContext.Current.Session.Remove(SESSION_SINGLETON);
}
结论

使用存储在会话对象中的单例对象,而不是使用单个会话键来存储信息,有许多优点。它对于整个会话中要存在的对象(分组逻辑项、影响分析、intellisense等)非常有用,特别是对于在用户完成特定过程之前网站上只需要一段时间的对象(当流程完成但会话将继续时,更容易识别变量滥用并节省资源)

是ASP.NET进程级别的<代码> Stutelon < /C>的一个很好的例子。任何轻量级的键值对都可以存储在网站中。这些键值对将在Web调用中保持可访问性。对于重的或资源密集的对象,应该考虑使用。