Last post Jan 02, 2009 05:30 PM by leep
Dec 31, 2008 08:37 PM|leep|LINK
ASP.NET 3.5, C# 3.0
I suspect there's something simple I'm missing. I have a set of data specific to a particular user's session that needs to be accessible across page requests and accessible from classes in a DLL (our business logic / objects). I can put all this data in
a class in the DLL (let's say MyState) and have the user's first page request create an instance of the MyState class and store a reference to it in the user's Session. Each page request could pull the MyState object from Session and use it (something like
(Session["MyState"] as MyState).blah ...). But I don't want the DLL referencing HttpContext.Current.Session because the DLL could be used with a Windows Forms front end in the future.
So the question is, how/where do I store a reference to this MyState object the UI has created so that it's "globally" accessible to all the classes in the DLL? I don't want to have to pass a reference to it to every method I call on a class in the DLL.
I initialy tried making a static class in the DLL with a static MyState property, but that was shared between all user sessions and I need each user session to have their own MyState instance, globally accesible to methods it calls into the DLL.
Session "global access" DLL
Dec 31, 2008 09:23 PM|WebD|LINK
You can look into have your code-behind files inherit from your own custom created Base Class, which in turn can inherit the System.Web.Ui.Page base class. The standard mock up is that your pages will directly inherit from System.Web.UI.Page, but you can
add an extra layer for your custom programming needs. This then will be accessible to all ASP.NET pages.
Dec 31, 2008 09:34 PM|leep|LINK
I'm not sure I'm clear on how this will allow me to access the session specific instance of the MyState object from anywhere in the DLL without touching HttpContext.Current.Session in the DLL or having to pass the instance to each method called into the
DLL. That does sound like a great way to ensure all pages have a common set of properties with their getter/setter coded in one common place though. [:)]
Dec 31, 2008 09:50 PM|WebD|LINK
You can create a shared function in your custom class.
Dec 31, 2008 10:50 PM|Momcilo|LINK
Ideal solution would be to create an interface, for example, "IUserState" with all methods you need in your code. Then you will have an implementation based on HttpContext.Current.Session (but your code would work with any implementation including mocks,
of course) and pass an instance to each business object that needs it.
Dec 31, 2008 11:23 PM|leep|LINK
I think I like where you're going with that. I'm not completely clear on what you were trying to describe though. Were you saying have my MyState class implement IUserState, MyState class is defined in the UI, IUserState interface is defined in the DLL.
the DLL only accesses it through its IUserState interface. If I made a Windows Forms front end, it would have it's own MyState class that implements the DLL's IUserState and manages state without Session, but the DLL still just accesses it via its IUserState
I'm still unclear on how/where the UI (in a web application, but should be the same for web or desktop) stores a reference to this object (which implements the DLL's IUserState) so that all the methods on classes in the DLL can access it (without using a
Dec 31, 2008 11:36 PM|Momcilo|LINK
Yes, MyState (I would call it HttpContextState) should implement IUserState. I would avoid static classes or properties, just pass an instance of MyState to every class that needs it. For example:
// This is code somewhere on your web page
UserLogin login = new UserLogin(new MyState());
bool loginOk = login.Execute(txtUsername.Text, txtPassword.Text);
Jan 02, 2009 05:30 PM|leep|LINK
I ended up using a slight compromise. I have a threading question about how I handled this at the end of this post.
The business logic/objects DLL will check to see if the UI is an ASP.NET app (HttpContext.Current != null). If so, it will pull a reference to a (or create a new) MyState object from HttpContext.Current.Session. If not, it will just use the current instance
of a (or create a new) MyState object. Here's example code of what I did:
1 namespace Lib
3 public static class General
5 private static MyState _myState =
7 public static MyState CurrentState
11 if (HttpContext.Current ==
13 // Our front-end is not an ASP.NET application so we can use the same instance of MyState always.
14 if (_myState ==
16 _myState = new MyState();
21 // Our front-end is an ASP.NET application. We have to use a different instance of MyState
22 // for each ASP.NET Session.
23 if (HttpContext.Current.Session["MyState"] ==
25 HttpContext.Current.Session["MyState"] =
27 // Grab this session's instance of MyState.
28 _myState = (HttpContext.Current.Session["MyState"]
30 return _myState;
Now in any codebehind page, and from any method in any class in the DLL, code can access Lib.General.CurrentState and have access to the current ASP.NET Session's "global" data. If I plug this DLL into a Windows Forms front end, it will have access through
the same means to one instance of the "global" data and the front end can still access it the exact same way (Lib.General.CurrentState).
My only question remaining at the moment is... With the way I'm doing this, and the way ASP.NET can have muliple users hitting it at the same time, do I have any multi-threaded concerns I should be aware of? Each ASP.NET Session (and so I'm assuming "thread")
has it's own instance of MyState, but isn't there realy only one instance of Lib.General._myState? Is this going to be a problem? If a 2nd Session accesses Lib.General.CurrentState, is it going to overwrite _myState with the reference to the 2nd Session's
MyState object causing the 1st Session to start accessing the 2nd's Sessions MyState? Each time 1st Session acccesses Lib.General.CurrentState it's changing _myState back to it's instance... so maybe it's only a problem if the 1st and 2nd Session access at
EXCATLY the same time?