我有一个Web应用程序,希望从数据库中提取用户设置并存储以供全局访问。将数据存储在Singleton对象还是Session对象中更合适?这两者之间有什么区别?
将数据存储为对象引用还是将其拆分为值类型对象(int和string)更好?
我有一个Web应用程序,希望从数据库中提取用户设置并存储以供全局访问。将数据存储在Singleton对象还是Session对象中更合适?这两者之间有什么区别?
将数据存储为对象引用还是将其拆分为值类型对象(int和string)更好?
会话(Session)就是为了这个目的。会话存储在全局缓存中(基本上是一个单例),由会话ID作为键。这样,您只获取所需会话的数据。如果使用单例模式,就基本上是复制全局缓存,您将不得不重新发明机制来独立地检索每个会话的数据。
可以放心地存储对象。让会话负责将其序列化为可恢复的形式。但是,要小心放入会话中的内容。如果存储太多的数据,您将消耗大量内存(假设是一个基于内存的缓存)。
会话对象,毫无疑问。
单例存在于进程级别。这意味着,如果在任何给定时刻有20个用户访问您的站点,则它们使用相同的单例对象。如果您不经常进行Web开发,很难习惯这个概念。
会话存在于用户级别。这意味着您可以按用户而不是按进程存储数据。
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";
public static void Dispose()
{
//Cleanup this object so that GC can reclaim space
System.Web.HttpContext.Current.Session.Remove(SESSION_SINGLETON);
}
结论
使用存储在Session对象中的单例对象比使用单独的会话键来存储信息有许多优点。这对于那些需要在整个会话期间存在的对象非常有用(分组逻辑项、影响分析、智能感知等),尤其是对于那些只需要在网站上的某个时间段内使用,直到用户完成特定流程的对象而言(这样可以更容易地识别变量的误用,并在流程完成但会话仍在继续时节省资源)。
public static SessionHandler GetInstance()
{
if (HttpContext.Current.Session["SessionHandler"] == null)
{
HttpContext.Current.Session["SessionHandler"] = new SessionHandler();
}
return (SessionHandler)HttpContext.Current.Session["SessionHandler"];
}
然后将其用作普通的单例。放入你需要的变量。