By orphan, I mean....
I put a value into the Session object. I use it. But it just "hangs out
there" because I didn't remove it.
Like I go to news.aspx, and read the object out of the Session... and
populate the values in news.aspx.
Then I go to a totally different place in my web app, never needing that
item I put in .Session again.
It just hangs out, taking up unnecessary resources.
The static thing. This was just the way you do a singleton in asp.net.
http://www.google.com/search?hl=en&q="asp.net"+singleton
Hmmm. You bring up an interesting point.
But even though its a static method, way down deep in the .GetInstance is
m_singletonInstance =
(WebSessionDataStore)System.Web.HttpContext.Current.Session[SESSION_OBJECT_G
UID];
So that part is Session/User Specific.
I do know I've had great success with it, in a multi user environment.
PS
Hints:
On a "login" , I usually clear the cache...........and also on a "logout".
What I mean is that when a user is verified, I go ahead an just make sure I
do a .Clear() , just in case the SessionID got stuck.
Sometimes the SessionID doesn't reset, even when you call Session.Abandon.
If the user clicks a logout button, I just call the .Clear() to make sure
there isn't something in Session memory orphaned.
That's kinda why I really like the Wrapper, I have control of when I need an
item, when I need to .Remove it, and when I need to wipe out everything.
Without a bunch of riddled Session object code throughout.
ids.Clear() is the method to call.
Below is my new 2.0 version. With a little extra check about the SessionID
You'll notice I have a IDataStore.
I also have a "WeakReference" implementation of this Interface.
You use a WeakReference, when you kinda want to cache stuff, but if there is
a big load on the server, the object gets released.
Aka, if the server is under load, and I cached up a list of departments or
something, the WeakReference will say "this isn't that important, release
it".
But the code below means "I need that object to be there no matter what".
I have a SimpleFactory that I throw a enum at, to get the 2 different
versions.
using System;
using System.Collections.Generic;
using System.Text;
namespace GranadaCoder.CachingFramework
{
[Serializable]
public class WebSessionDataStore //: IDataStore
{
//Guid ensures that uniqueid that won't be duplicated by accident
private const string SESSION_OBJECT_GUID =
"ABCABCAB-3754-4074-A007-051F9B64CA9E";
private static WebSessionDataStore _singletonInstance ;//= null;
private Dictionary<string, object> _memoryStore ;//= null;
private static string _sessionId = string.Empty;
#region Singleton Area
private WebSessionDataStore()
{
this._memoryStore = new Dictionary<string, object>();
}
/// <summary>
/// Singleton representing WebSessionDataStore.
/// </summary>
/// <returns></returns>
public static WebSessionDataStore GetInstance()
{
if (null != System.Web.HttpContext.Current)
{
if (null != System.Web.HttpContext.Current.Session)
{
bool resetSession = false;
if (System.Web.HttpContext.Current.Session.IsNewSession)
{
resetSession = true;
}
if
(System.Web.HttpContext.Current.Session.SessionID.ToUpper() !=
_sessionId.ToUpper())
{
resetSession = true;
}
if (resetSession)
{
_singletonInstance = null; //Its a new Session, to
blow away the singleton, so a new one is created.
}
else
{
if (null !=
System.Web.HttpContext.Current.Session[SESSION_OBJECT_GUID])
{
_singletonInstance =
(WebSessionDataStore)System.Web.HttpContext.Current.Session[SESSION_OBJECT_G
UID];
}
}
}
}
if (null == _singletonInstance)
{
_singletonInstance = new WebSessionDataStore();
System.Web.HttpContext.Current.Session[SESSION_OBJECT_GUID]
= _singletonInstance;
_sessionId =
System.Web.HttpContext.Current.Session.SessionID;//set the sessionId//
}
return _singletonInstance;
}
#endregion
#region IDataStore Members
/// <summary>
/// Removes all objects in the DataStore.
/// </summary>
public void Clear()
{
_memoryStore.Clear();
}
/// <summary>
/// Adds an object with the specified key.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The object to be added.</param>
public void Add(string key, object value)
{
if (_memoryStore.ContainsKey(key))
{
_memoryStore.Remove(key);
}
_memoryStore.Add(key, value);
}
//The next method doesn't do anything
////// public void AddNotRemovable(string key, object value)
////// {
////// this.Add( key, value );
////// }
/// <summary>
/// Removes the object using the specified key.
/// </summary>
/// <param name="key">The key used originally used to Add the item
to the DataStore.</param>
/// <returns></returns>
public object Remove(string key)
{
// see
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.html#remove(java.lang.Object)
// for java method, which returns the object you removed, in
case
// you want to do something with it
object returnObject = null;
if (null != this._memoryStore)
{
if (_memoryStore.ContainsKey(key))
{
returnObject = this._memoryStore[key];
_memoryStore.Remove(key);
}
}
return returnObject;
}
/// <summary>
/// Gets the <see cref="Object"/> with the specified key.
/// </summary>
/// <value></value>
public object this[string key]
{
get
{
if(this._memoryStore.ContainsKey(key))
{
if (null != _memoryStore[key])
{
return _memoryStore[key];
}
}
return null;
}
}
/// <summary>
/// Gets the number of items in the DataStore.
/// </summary>
/// <value>The size.</value>
public int Size
{
get
{
if (null != _memoryStore)
{
return _memoryStore.Count;
}
return 0;
}
}
#endregion
}
}