I have a web application where I would like to pull user settings from a database and store them for Global access. Would it make more sense to store the data in a Singleton, or a Session object? What's the difference between the two?
Is it better to store the data as an obj开发者_如何学Pythonect reference or break it up into value type objects (ints and strings)?
Session. That's what it's for. The session is stored in the global cache (basically a singleton), keyed by the session id. That way, you get only the data for the session of interest. Using a singleton would basically be replicating the global cache and you'd have to reinvent the mechanism to retrieve data for each session independently.
Go ahead and store the object. Let the Session worry about serializing it to something that can be restored. Be careful, though, with what you put in the Session. You don't want to store too much data there or you'll use up a lot of memory (assuming an in-memory cache).
Session object, definitely.
Singletons exist at the process level. This means that if you have 20 users accessing your site at any given moment, they're using the same singleton object. It's difficult to get used to this concept if you're not doing web development a lot.
Sessions exist at the user level. That means you can store data per user, not per process.
If these settings will be used for all users of the site, put them in a singleton or in application cache. If they are specific to each user, put them in session.
Use object references when adding to app or session cache - I believe that value types will get boxed so they look like objects to the cache. If you use a singleton, it could go either way.
This is taken from an old document but it is still very valid and works a treat... I'll put the link contents here, especially because it is an old link which may disappear. Taken from here.
Background
The Session object in ASP.Net can be used to store information that is specific to an individual user of the site. The Session is indexed by a key name, and when it is used directly in such a manner it can lead to a large number of individual session names. An alternative approach is to instead create a singleton object to group related items and store that object with a given key name. The "singleton" is a common design pattern that specifies how to ensure that only a single instance of a class exists at any time.
Advantages of Singleton Session Objects
- Grouping of session items for organization purposes
- Especially useful for a series of pages on a transient process such as registration on a site. Once the process is complete the object can be cleared from the session so the memory can be reclaimed (better use of server resources)
- Impact analysis of changes to session information is much easier
- Identify areas of the site that are misusing information (much clearer than just using the name of the variable to determine if it is appropriate to use)
- Intellisense for property names and types once access the object
Disadvantages of Singleton Session Objects
More difficult to see the number of individual items in session ASP.Net Trace results does not show the values inside the object Performance degradation when using out of process session state storage (affects serialization)
Implementation
The first implementation step is to create a class file that represents the logical grouping of items that should be stored together in the single object. The following is a sample class that demonstrates the technique:
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;
}
}
A page that wants to use this object simply does the following:
singleton oSingleton = singleton.GetCurrentSingleton();
oSingleton.FirstName = "Robert";
oSingleton.LastName = "Boedigheimer";
Typically this technique will store many more variables in the given class or will be used for a series of web pages that perform a process. Another advantage of using this for a process on a web site is that all of the memory required for the session variables can be cleared out by simply removing the reference to the singleton object. The class can implement a method that clients can use to clear the reference, it can be named Dispose() to follow the typical .Net pattern when a class provides a way to cleanup:
public static void Dispose()
{
//Cleanup this object so that GC can reclaim space
System.Web.HttpContext.Current.Session.Remove(SESSION_SINGLETON);
}
Conclusion
There are many advantages to using singleton objects stored in the Session object rather than using individual session keys for storing information. It is useful for objects that are meant to exist for the entire session (grouping logical items, impact analysis, intellisense, etc) and especially for objects that are really only needed for a period of time on a web site until the user completes a particular process (much easier to identify misuse of variables and to conserve resources when the process is completed but the session will continue).
Sometimes I like the below method. It takes care of the problems with magic strings and unset session variables. It also runs the singleton at the session level rather than the application level.
public static SessionHandler GetInstance()
{
if (HttpContext.Current.Session["SessionHandler"] == null)
{
HttpContext.Current.Session["SessionHandler"] = new SessionHandler();
}
return (SessionHandler)HttpContext.Current.Session["SessionHandler"];
}
Then just use it as a normal singleton. Putting in the variables you need.
精彩评论