Introduction
This is intended to be a simple solution to sharing session data across applications. This implementation allows you to use the out of the box session providers that ship with ASP.NET without modifying any stored procedures, or creating custom session store providers.
Background
There was a large project going on at work, part of which involved splitting our one large website into smaller logical areas of functionality. This would provide us with more flexibility and manageability of our products. The only problem was, how would we share session data across applications?
Our current environment uses a SQL session store, so my first suggestion was to simply modify one of the stored procs to give all applications the same name, thus sharing session. That was quickly shot down by coworkers because they felt it would cause a support hole in the case that Microsoft would have to come in to troubleshoot anything related to session data. So, they decided to create custom session store providers. What they ended up doing is essentially creating exact code duplicates of the MS implementations for SQL and State Server session stores, and hacking in a few lines to change the application name (I am not sure how that is any better that changing a stored proc, but that was the decision).
As time came to actually implement this in our applications, I looked over the proof of concept, and found myself unable to actually use all that copied code simply to share session data. I just couldn't believe that there wasn't an easier way to solve this problem.
After spending about an hour searching the Internet, and not finding anything better, I decided to dig into the session manager code using Reflector to see if I could find anything.
Here's what I came up with...
Using the code
This shared session solution I came up with is fairly simple to use. Simply plug in the SharedSessionModule
...
In the web.config of each application you would like to share session data for, add the following HTTP module:
<httpModules>
<add name="SharedSessionModule" type="Femiani.Web.Modules.SharedSessionModule,
Femiani.Web.Modules.SharedSessionModule"/>
</httpModules>
Then, set your application name:
<appSettings>
<add key="ApplicationName" value="SharedWeb"/>
</appSettings>
Points of interest
After digging around for a while, I found out where the session stores were getting the application name from. Then, using an HTTP module and some Reflection, I manually set the application name when the web application starts up.
public class SharedSessionModule : IHttpModule
{
#region IHttpModule Members
public void Init(HttpApplication context)
{
try
{
string appName = ConfigurationManager.AppSettings["ApplicationName"];
if (!string.IsNullOrEmpty(appName))
{
FieldInfo runtimeInfo = typeof(HttpRuntime).GetField("_theRuntime",
BindingFlags.Static | BindingFlags.NonPublic);
HttpRuntime theRuntime = (HttpRuntime)runtimeInfo.GetValue(null);
FieldInfo appNameInfo = typeof(HttpRuntime).GetField("_appDomainAppId",
BindingFlags.Instance | BindingFlags.NonPublic);
appNameInfo.SetValue(theRuntime, appName);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
public void Dispose()
{
}
#endregion
}
And that's it! Pretty simple.