Sunday, February 13, 2011

How to provide a Session/Host object for use in both a windows and web application?

I have a web application that makes heavy use of the Session state to store information about the current user, their personal settings, record their session history and so on.

I have found myself retrieving this session information in my business layer, like so:

((UserSession)HttpContext.Current.Session["UserSession"]).User.Info

This poses a problem - at some point in the future my application will have a Windows client which obviously cannot reference the web Session state. So I need a host or customized session class that I can reference in my business layer that is agnostic of whether the application is running on the web or desktop. Something like:

IHost.User.Info

Behind the scenes, the web implementation will obviously utilize the Session state to store information, but I need to hide this away from my business layer. Has anyone solved this problem or got any practival advice on how best to approach this?

Help appreciated.

  • I guess you need to create a webservice or RESTfull service. The service will return an XML file representing your user information. You will be able to invoke the service wither from you windows or web application.

    flesh : Im not sure I explained my problem very well. The user info is populated when they login, so I dont envisage calling a web service. On the web I have to store user info in the Session state but the Session is not available in a windows client and I want to use the same BLL in both web and client
    mnour : Well, I have suggested using webservcies because this is the ideal solution for this kind of abstraction you need across your applications. You can make a method in your webservice for login and invoked before calling: "GetUserInfo" method which retrieve the user info stored in the WS session.
    From mnour
  • Assuming that the business layer is a separate DLL, I would never add a reference to System.Web and in consequence I would never use the Session object directly. This would lead to a different design of the business layer and of the exposed interfaces to a client (either web or winforms).

    That said, as a quick workaround I would suggest to write a wrapper class in your business layer that hides the Session object from your code. Your calls from code will be something like this:

    ((UserSession) DualContext.Current["UserSession"]).User.Info
    

    and the wrapper implementation will be something like this (not completed and tested):

    public class DualContext 
    {
       private Dictionary<string, object> winFormsSession = new Dictionary<string, object>();
       private static readonly DualContext instance = new DualContext();
    
       public static DualContext Current
       {
          get {  return instance; }
       }
    
       public object this[string key]
       {
          get 
          {
             if (HttpContext.Current != null)
                return HttpContext.Current.Session[key];
             else
                return winFormsSession[key];
          }
          set 
          {
             if (HttpContext.Current != null)
                HttpContext.Current.Session[key] = value;
             else
                winFormsSession[key] = value;
          }
       }
    }
    
    From Panos
  • It would take some re-architecting, but if you switch from using Session State to User Profiles you could then use Client Application Services to share the information.

    http://msdn.microsoft.com/en-us/library/bb384297.aspx

0 comments:

Post a Comment