ASP.NET MVC HttpContext.Session object - asp.net-mvc

I have a question. I've built custom class in my project that contains public static property ctx and assingn HttpContext.Current object to it. In runtime that property seem to reference HttpContext object, but ctx.Session class is null. When i debug my app the left side of an expression (ctx) is not exactly the same as right side (HttpContext.Current). why this is happening?
Grettings

HttpContext.Current is a singleton only for that request. By assigning the HttpContext.Current to a static variable you would be sharing this HttpContext.Current to an entire scope, which may not be right.
Session is a per user object while, static is an application wide object. Use static wisely.

What I would do would be something like this.
1- a static class (ex: ContextFactory) which provides current httpcontext. If it has HttpContext.Current, then is provides that value, if not then it provides an assigned context. In your case, new Mock<HttpContextBase>();
public static class ContextFactory
{
private static HttpContextBase current = null;
public static HttpContextBase Current
{
get { return current ?? HttpContext.Current; }
set { current = value; }
}
}
2- Then I alter the code UserSess to
public static class UserSess
{
public static UserID
{
get { return ContextFactory.Current.Session["UserID"]; }
set { ContextFactory.Current.Session["UserID"] = value; }
}
//...
}
sincerely

Related

NInject, nHibernate, and auditing in ASP.NET MVC

I am working on an inherited application which makes use of NInject and nHibernate as part of an ASP.NET MVC (C#) application. Currently, I'm looking at a problem with the auditing of modifications. Each entity has ChangedOn/ChangedBy and CreatedOn/CreatedBy fields, which are mapped to database columns. However, these either get filled with the wrong username or no username at all. I think this is because it has been configured in the wrong way, but I don't know enough about nHibernate and NInject to solve the issue, so I hope someone can help. Below some code snippets to hopefully provide sufficient insight in the application.
Creating the session factory and session:
public class NHibernateModule : NinjectModule
{
public override void Load()
{
Bind<ISessionFactory>().ToProvider(new SessionFactoryProvider()).InSingletonScope();
Bind<ISession>().ToProvider(new SessionProvider()).InRequestScope();
Bind<INHibernateUnitOfWork>().To<NHibernateUnitOfWork>().InRequestScope();
Bind<User>().ToProvider(new UserProvider()).InRequestScope();
Bind<IStamper>().ToProvider(new StamperProvider()).InRequestScope();
}
}
public class SessionProvider : Provider<ISession>
{
protected override ISession CreateInstance(IContext context)
{
// Create session
var sessionFactory = context.Kernel.Get<ISessionFactory>();
var session = sessionFactory.OpenSession();
session.FlushMode = FlushMode.Commit;
return session;
}
}
public class SessionFactoryProvider : Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
var connectionString = ConfigurationManager.ConnectionStrings["DefaultConnectionString"].ToString();
var stamper = context.Kernel.Get<IStamper>();
return NHibernateHelper.CreateSessionFactory(connectionString, stamper);
}
}
public class StamperProvider : Provider<IStamper>
{
protected override IStamper CreateInstance(IContext context)
{
System.Security.Principal.IPrincipal user = HttpContext.Current.User;
System.Security.Principal.IIdentity identity = user == null ? null : user.Identity;
string name = identity == null ? "Unknown" : identity.Name;
return new Stamper(name);
}
}
public class UserProvider : Provider<User>
{
protected override UserCreateInstance(IContext context)
{
var userRepos = context.Kernel.Get<IUserRepository>();
System.Security.Principal.IPrincipal user = HttpContext.Current.User;
System.Security.Principal.IIdentity identity = user == null ? null : user.Identity;
string name = identity == null ? "" : identity.Name;
var user = userRepos.GetByName(name);
return user;
}
}
Configuring the session factory:
public static ISessionFactory CreateSessionFactory(string connectionString, IStamper stamper)
{
// Info: http://wiki.fluentnhibernate.org/Fluent_configuration
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(connectionString))
.Mappings(m =>
{
m.FluentMappings
.Conventions.Add(PrimaryKey.Name.Is(x => "Id"))
.AddFromAssemblyOf<NHibernateHelper>();
m.HbmMappings.AddFromAssemblyOf<NHibernateHelper>();
})
// Register
.ExposeConfiguration(c => {
c.EventListeners.PreInsertEventListeners =
new IPreInsertEventListener[] { new EventListener(stamper) };
c.EventListeners.PreUpdateEventListeners =
new IPreUpdateEventListener[] { new EventListener(stamper) };
})
.BuildSessionFactory();
}
Snippet from the eventlistener:
public bool OnPreInsert(PreInsertEvent e)
{
_stamper.Insert(e.Entity as IStampedEntity, e.State, e.Persister);
return false;
}
As you can see the session factory is in a singleton scope. Therefore the eventlistener and stamper also get instantiated in this scope (I think). And this means that when the user is not yet logged in, the username in the stamper is set to an empty string or "Unknown".
I tried to compensate for this problem, by modifying the Stamper. It checks if the username is null or empty. If this is true, it tries to find the active user, and fill the username-property with that user's name:
private string GetUserName()
{
if (string.IsNullOrWhiteSpace(_userName))
{
var user = ServiceLocator.Resolve<User>();
if (user != null)
{
_userName = user.UserName;
}
}
return _userName;
}
But this results in a completely different user's name, which is also logged in to the application, being logged in the database. My guess this is because it resolves the wrong active user, being the last user logged in, instead of the user that started the transaction.
The offending parts are here:
Bind<ISessionFactory>().
.ToProvider(new SessionFactoryProvider())
.InSingletonScope();
Bind<IStamper>()
.ToProvider(new StamperProvider())
.InRequestScope();
And later on:
public class SessionFactoryProvider : Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
// Unimportant lines omitted
var stamper = context.Kernel.Get<IStamper>();
return NHibernateHelper.CreateSessionFactory(connectionString, stamper);
}
}
public class StamperProvider : Provider<IStamper>
{
protected override IStamper CreateInstance(IContext context)
{
// Unimportant lines omitted
string name = /* whatever */
return new Stamper(name);
}
}
Let's analyze what's going on with the code:
The ISessionFactory is bound as single-instance. There will only ever be one throughout the lifetime of the process. This is fairly typical.
The ISessionFactory is initialized with SessionFactoryProvider which immediately goes out to get an instance of IStamper, and passes this as a constant argument to initialize the session factory.
The IStamper in turn is initialized by the StamperProvider which initializes a Stamper class with a constant name set to the current user principal/identity.
The net result of this is that as long as the process is alive, every single "stamp" will be assigned the name of whichever user was first to log in. This might even be the anonymous user, which explains why you're seeing so many blank entries.
Whoever wrote this only got half the equation right. The IStamper is bound to the request scope, but it's being supplied to a singleton, which means that only one IStamper will ever be created. You're lucky that the Stamper doesn't hold any resources or have any finalizers, otherwise you'd probably end up with a lot of ObjectDisposedException and other weird errors.
There are three possible solutions to this:
(Recommended) - Rewrite the Stamper class to look up the current user on each call, instead of being initialized with static user info. Afterward, the Stamper class would no longer take any constructor arguments. You can the bind the IStamper InSingletonScope instead of InRequestScope.
Create an abstract IStamperFactory with a GetStamper method, and a concrete StamperFactory which implements it by wrapping the IKernel instance. Bind these together InSingletonScope. Have your concrete factory return kernel.Get<IStamper>(). Modify the session factory to accept and hold an IStamperFactory instead of an IStamper. Each time it needs to stamp, use the factory to get a new IStamper instance.
Change the ISessionFactory to be InRequestScope. Not recommended because it will hurt performance and potentially mess up ID generators if you don't use DB-generated identities, but it will solve your auditing problem.
Aaronaught, you're analysis describes exactly what I suspected. However, I found there is a fourth solution which is easier and more straightforward IMHO.
I modified the sessionprovider, such that the call to OpenSession takes an instance of IInterceptor as argument. As it turns out, the event listeners aren't actually supposed to be used for auditing (a bit of a rant, but other than that he is right, according to Fabio as well).
The AuditInterceptor implements OnFlushDirty (for auditing existing entities) and OnSave (for auditing newly created entities). The SessionProvider looks as below:
public class SessionProvider : Provider<ISession>
{
protected override ISession CreateInstance(IContext context)
{
// Create session
System.Security.Principal.IPrincipal user = HttpContext.Current.User;
System.Security.Principal.IIdentity identity = user == null ? null : user.Identity;
string name = identity == null ? "" : identity.Name;
var sessionFactory = context.Kernel.Get<ISessionFactory>();
var session = sessionFactory.OpenSession(new AuditInterceptor(name));
session.FlushMode = FlushMode.Commit;
return session;
}
}

Questions regarding HttpContext, HttpContextBase, and Action Filters

I'm try to build a static property on a static class that will basically return a cookie value, to be used across my MVC site (MVC 3, if it matters). Something like this:
public static class SharedData
{
public static string SomeValue
{
get
{
if (HttpContext.Current.Request.Cookies["SomeValue"] == null)
{
CreateNewSomeValue();
}
return HttpContext.Current.Request.Cookies["SomeValue"].Value.ToString();
}
}
}
I need to access this from within controller actions, global.asax methods, and action filters. But the problem is, when action filters run, HttpContext is not available. Right now, I have to have a separate static method just to pull the cookie from the filter context that I pass in, which seems awkward.
What is the best solution for building such a static method for retrieving a cookie value like this that works from both controller actions and action filters? Or is there a better approach for doing something like this?
Thanks in advance.
The call to the static HttpContext.Current is not good design. Instead, create an extension method to access the cookie from an instance of HttpContext and HttpContextBase.
I wrote a little helper for you. You can use it to perform your functionality from within an action filter.
public static class CookieHelper
{
private const string SomeValue = "SomeValue";
public static string get_SomeValue(this HttpContextBase httpContext)
{
if(httpContext.Request.Cookies[SomeValue]==null)
{
string value = CreateNewSomeValue();
httpContext.set_SomeValue(value);
return value;
}
return httpContext.Request.Cookies[SomeValue].Value;
}
public static void set_SomeValue(this HttpContextBase httpContext, string value)
{
var someValueCookie = new HttpCookie(SomeValue, value);
if (httpContext.Request.Cookies.AllKeys.Contains(SR.session))
{
httpContext.Response.Cookies.Set(someValueCookie);
}
else
{
httpContext.Response.Cookies.Add(someValueCookie);
}
}
}
Note: You could easily make these methods work on HttpContext instead just by replacing the HttpContextBase parameter with HttpContext.
As JohnnyO pointed out above, I had access to HttpContext from within my action filter all along. At least, in the particular action filter method where this was needed. There may have been some other filter/method that did not have access at one point, but for now, this is working as I need it to.

Response is not available in this context when creation cookie's

hi i defined one class to create cookie by received parameter's from user. when i want to add cookie to context i receive an exception.
My Class
public static class ManageCookies
{
public static void Create(string name, string value)
{
HttpCookie cookie = new HttpCookie(name);
cookie.Value = value;
cookie.Expires = DateTime.Now.AddYears(1);
HttpContext.Current.Response.Cookies.Add(cookie);
}
}
Occured Exception: Response is not available in this context.
i know it is connected with the context within the current sub is executing.
i whould suggest my function to pass the current HttpResponse as a parametter to that!
public static class ManageCookies
{
public static void Create(string name, string value, HttpResponse response)
{
HttpCookie cookie = new HttpCookie(name);
cookie.Value = value;
cookie.Expires = DateTime.Now.AddYears(1);
response.Cookies.Add(cookie);
}
public static void PrePareForApplicationStart()
{
Create("somecookie", "somevalue", _context);
}
}
this is correct way? why? and are you have another way?
UPDATE: Oppps! using this way still have First Exception! :(( Help Help
ManageCookies manager = new ManageCookies(this.Context);
manager.PrePareForApplicationStart();
i use above code to send HTTPContext object to defined class. it called from Application_Start event.
and ManageCookies class updated as below:
public class ManageCookies
{
private HttpContext _context;
public ManageCookies(HttpContext context)
{
this._context = context;
}
}
i use this variable (_context) to adding cookies!
The code you provided is not a problem the problem is where you call it from. If you call it after the response is flushed or from a thread other than the one assigned to process your request - you can get all sorts of problems
In response to Sadegh clarification:
This is exactly the point. Application Start happens only once during application lifetime. And I guess you want this cookie to be delivered as a part of every response. In other words on ApplicationStart is not the right place to do it. You can do it at any moment during page lifecycle BEFORE the end of the PreRender

Session variables in ASP.NET MVC

I am writing a web application that will allow a user to browse to multiple web pages within the website making certain requests. All information that the user inputs will be stored in an object that I created. The problem is that I need this object to be accessed from any part of the website and I don't really know the best way to accomplish this. I know that one solution is to use session variables but I don't know how to use them in asp .net MVC. And where would I declare a session variable? Is there any other way?
I would think you'll want to think about if things really belong in a session state. This is something I find myself doing every now and then and it's a nice strongly typed approach to the whole thing but you should be careful when putting things in the session context. Not everything should be there just because it belongs to some user.
in global.asax hook the OnSessionStart event
void OnSessionStart(...)
{
HttpContext.Current.Session.Add("__MySessionObject", new MySessionObject());
}
From anywhere in code where the HttpContext.Current property != null you can retrive that object. I do this with an extension method.
public static MySessionObject GetMySessionObject(this HttpContext current)
{
return current != null ? (MySessionObject)current.Session["__MySessionObject"] : null;
}
This way you can in code
void OnLoad(...)
{
var sessionObj = HttpContext.Current.GetMySessionObject();
// do something with 'sessionObj'
}
The answer here is correct, I however struggled to implement it in an ASP.NET MVC 3 app. I wanted to access a Session object in a controller and couldn't figure out why I kept on getting a "Instance not set to an instance of an Object error". What I noticed is that in a controller when I tried to access the session by doing the following, I kept on getting that error. This is due to the fact that this.HttpContext is part of the Controller object.
this.Session["blah"]
// or
this.HttpContext.Session["blah"]
However, what I wanted was the HttpContext that's part of the System.Web namespace because this is the one the Answer above suggests to use in Global.asax.cs. So I had to explicitly do the following:
System.Web.HttpContext.Current.Session["blah"]
this helped me, not sure if I did anything that isn't M.O. around here, but I hope it helps someone!
Because I dislike seeing "HTTPContext.Current.Session" about the place, I use a singleton pattern to access session variables, it gives you an easy to access strongly typed bag of data.
[Serializable]
public sealed class SessionSingleton
{
#region Singleton
private const string SESSION_SINGLETON_NAME = "Singleton_502E69E5-668B-E011-951F-00155DF26207";
private SessionSingleton()
{
}
public static SessionSingleton Current
{
get
{
if ( HttpContext.Current.Session[SESSION_SINGLETON_NAME] == null )
{
HttpContext.Current.Session[SESSION_SINGLETON_NAME] = new SessionSingleton();
}
return HttpContext.Current.Session[SESSION_SINGLETON_NAME] as SessionSingleton;
}
}
#endregion
public string SessionVariable { get; set; }
public string SessionVariable2 { get; set; }
// ...
then you can access your data from anywhere:
SessionSingleton.Current.SessionVariable = "Hello, World!";
Well, IMHO..
never reference a Session inside your view/master page
minimize your useage of Session. MVC provides TempData obj for this, which is basically a Session that lives for a single trip to the server.
With regards to #1, I have a strongly typed Master View which has a property to access whatever the Session object represents....in my instance the stongly typed Master View is generic which gives me some flexibility with regards to strongly typed View Pages
ViewMasterPage<AdminViewModel>
AdminViewModel
{
SomeImportantObjectThatWasInSession ImportantObject
}
AdminViewModel<TModel> : AdminViewModel where TModel : class
{
TModel Content
}
and then...
ViewPage<AdminViewModel<U>>
If you are using asp.net mvc, here is a simple way to access the session.
From a Controller:
{Controller}.ControllerContext.HttpContext.Session["{name}"]
From a View:
<%=Session["{name}"] %>
This is definitely not the best way to access your session variables, but it is a direct route. So use it with caution (preferably during rapid prototyping), and use a Wrapper/Container and OnSessionStart when it becomes appropriate.
HTH
Although I don't know about asp.net mvc, but this is what we should do in a normal .net website. It should work for asp.net mvc also.
YourSessionClass obj=Session["key"] as YourSessionClass;
if(obj==null){
obj=new YourSessionClass();
Session["key"]=obj;
}
You would put this inside a method for easy access.
HTH
There are 3 ways to do it.
You can directly access HttpContext.Current.Session
You can Mock HttpContextBase
Create a extension method for HttpContextBase
I prefer 3rd way.This link is good reference.
Get/Set HttpContext Session Methods in BaseController vs Mocking HttpContextBase to create Get/Set methods
My way of accessing sessions is to write a helper class which encapsulates the various field names and their types. I hope this example helps:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.SessionState;
namespace dmkp
{
/// <summary>
/// Encapsulates the session state
/// </summary>
public sealed class LoginInfo
{
private HttpSessionState _session;
public LoginInfo(HttpSessionState session)
{
this._session = session;
}
public string Username
{
get { return (this._session["Username"] ?? string.Empty).ToString(); }
set { this._session["Username"] = value; }
}
public string FullName
{
get { return (this._session["FullName"] ?? string.Empty).ToString(); }
set { this._session["FullName"] = value; }
}
public int ID
{
get { return Convert.ToInt32((this._session["UID"] ?? -1)); }
set { this._session["UID"] = value; }
}
public UserAccess AccessLevel
{
get { return (UserAccess)(this._session["AccessLevel"]); }
set { this._session["AccessLevel"] = value; }
}
}
}
Great answers from the guys but I would caution you against always relying on the Session. It is quick and easy to do so, and of course would work but would not be great in all cicrumstances.
For example if you run into a scenario where your hosting doesn't allow session use, or if you are on a web farm, or in the example of a shared SharePoint application.
If you wanted a different solution you could look at using an IOC Container such as Castle Windsor, creating a provider class as a wrapper and then keeping one instance of your class using the per request or session lifestyle depending on your requirements.
The IOC would ensure that the same instance is returned each time.
More complicated yes, if you need a simple solution just use the session.
Here are some implementation examples below out of interest.
Using this method you could create a provider class along the lines of:
public class CustomClassProvider : ICustomClassProvider
{
public CustomClassProvider(CustomClass customClass)
{
CustomClass = customClass;
}
public string CustomClass { get; private set; }
}
And register it something like:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ICustomClassProvider>().UsingFactoryMethod(
() => new CustomClassProvider(new CustomClass())).LifestylePerWebRequest());
}
You can use ViewModelBase as base class for all models , this class will take care of pulling data from session
class ViewModelBase
{
public User CurrentUser
{
get { return System.Web.HttpContext.Current.Session["user"] as User };
set
{
System.Web.HttpContext.Current.Session["user"]=value;
}
}
}
You can write a extention method on HttpContextBase to deal with session data
T FromSession<T>(this HttpContextBase context ,string key,Action<T> getFromSource=null)
{
if(context.Session[key]!=null)
{
return (T) context.Session[key];
}
else if(getFromSource!=null)
{
var value = getFromSource();
context.Session[key]=value;
return value;
}
else
return null;
}
Use this like below in controller
User userData = HttpContext.FromSession<User>("userdata",()=> { return user object from service/db });
The second argument is optional it will be used fill session data for that key when value is not present in session.

StructureMap IOC/DI and object creation

I'm building small web shop with asp.net mvc and Structuremap ioc/di. My Basket class uses session object for persistence, and I want use SM to create my basket object through IBasket interface. My basket implementation need HttpSessionStateBase (session state wrapper from mvc) in constructor, which is available inside Controller/Action. How do I register my IBasket implementation for SM?
This is my basket interface:
public interface IBasketService {
BasketContent GetBasket();
void AddItem(Product productItem);
void RemoveItem(Guid guid);
}
And SM registration:
ForRequestedType(typeof (IBasketService)).TheDefaultIsConcreteType(typeof (StoreBasketService));
But my StoreBasketService implementation has constructor:
public StoreBasketService(HttpSessionStateBase sessionState)
How do I provide HttpSessionStateBase object to SM, which is available only in controller?
This is my first use of SM IOC/DI, and cann't find solution/example in official documentation and web site ;)
If you absolutely have to have your StoreBasketService use the session, I'd be tempted to define an interface and wrapper around HttpSessionState instead of using HttpSessionStateBase so that you can register it with StructureMap as well.The wrapper would get the session state from the current context. Register the wrapper with StructureMap and then have your StoreBasketService take the interface as the argument to the constructor. Structure map should then know how to create an instance of the interface wrapper and inject it into your StoreBasketService class.
Using an interface and wrapper will allow you to mock the wrapper in your unit tests, muc in the same way HttpSessionStateBase allows mocking the actual session.
public interface IHttpSessionStateWrapper
{
HttpSessionState GetSessionState();
}
public class HttpSessionStateWrapper : IHttpSessionStateWrapper
{
public virtual HttpSessionState GetSessionState()
{
return HttpContext.Current.Session;
}
}
ForRquestedType(typeof(IHttpSessionStateWrapper))
.TheDefaultIsConcreteType(typeof(IHttpSessionStateWrapper));
public class StoreBasketService
{
HttpSessionState session;
public StoreBasketService( IHttpSessionstateWrapper wrapper )
{
session = wrapper.GetSessionState();
}
// basket implementation ...
}
However, you can have StructureMap actually store your basket in the session using .CacheBy(InstanceScope.HttpContext) when registering it. It may actually be better to have your StoreBasketService implement internal storage instead of storing things in the session -- then you lose the dependency on the session state entirely (from the perspective of your class) and your solution could be simpler. Your internal storage could be a Dictionary<Guid,Product> since this is how you access them via your interface.
See also:
http://www.lostechies.com/blogs/chad_myers/archive/2008/07/15/structuremap-basic-scenario-usage.aspx
http://www.lostechies.com/blogs/chad_myers/archive/2008/07/17/structuremap-medium-level-usage-scenarios.aspx
ForRequestedType<IBasketService>()
.TheDefault.Is.OfConcreteType<StoreBasketService>()
.WithCtorArg("sessionState").EqualTo(HttpContext.Current.Session);
?? does that work?
I just started with StructureMap, and I do not get the results you are describing.
I performed a simple test using a simple class, configuring Structuremap to cacheby HttpContext, and from what I can see, CacheBy.HttpContext means within the same request you will get the same instance... not within the same Session
The constructor of my class, sets the date/time in a private field
I have a button which gets 2 instances of MyClass with one second interval...
It then display the time of both instances in a label.
Pressing the first time this button, object A and B are same instance, as their creation time is exactly the same, as expected.
Clicking the button a second time, you would expect the creation time to not have changed if instances would be cached in session... however, in my test I get a new creation time ...
Structuremap configuration:
ObjectFactory.Initialize(x=>x.ForRequestedType<MyClass>(). CacheBy(InstanceScope.HttpContext));
Button clicked event of test page
protected void btnTest_Click(object sender, EventArgs e)
{
MyClass c = ObjectFactory.GetInstance<MyClass>();
System.Threading.Thread.Sleep(1000);
MyClass b = ObjectFactory.GetInstance<MyClass>();
lblResult.Text = String.Format("cache by httpcontext First:{0} Second:{1} session id {2} ", c.GetTimeCreated(), b.GetTimeCreated(),Session.SessionID);
}
MyClass
public class MyClass
{
private DateTime _timeCreated;
public MyClass()
{
_timeCreated = DateTime.Now;
}
public string GetTimeCreated()
{
return _timeCreated.ToString("dd/MM/yyyy hh:mm:ss");
}
}
You could also use one of the ObjectFactory.Inject methods to inject the HttpSessionStateBase into StructureMap. It would then invoke the constructor with the injected HttpSessionStateBase.
I just made my first attempt at creating an custom scope... build a small web application with it, and as far as I can see, it seems to work. This will cache the object inside the current user session and will return the same object as long as you remain inside the same session:
public class HttpSessionBuilder : CacheInterceptor
{
private readonly string _prefix = Guid.NewGuid().ToString();
protected override CacheInterceptor clone()
{
return this;
}
private string getKey(string instanceKey, Type pluginType)
{
return string.Format("{0}:{1}:{2}", pluginType.AssemblyQualifiedName, instanceKey, this._prefix);
}
public static bool HasContext()
{
return (HttpContext.Current.Session != null);
}
protected override bool isCached(string instanceKey, Type pluginType)
{
return HttpContext.Current.Session[this.getKey(instanceKey, pluginType)] != null;
}
protected override object retrieveFromCache(string instanceKey, Type pluginType)
{
return HttpContext.Current.Session[this.getKey(instanceKey, pluginType)];
}
protected override void storeInCache(string instanceKey, Type pluginType, object instance)
{
HttpContext.Current.Session.Add(this.getKey(instanceKey, pluginType), instance);
}
}
You have to configure the ObjectFactory as follows in the global.asax Application_start
ObjectFactory.Initialize(x=>
x.ForRequestedType<MyClass>().InterceptConstructionWith(new HttpSessionBuilder()));

Resources