ProfK
ProfK

Reputation: 51084

How can I maintain shared state in a Windows Forms app in a way like Session in ASP.NET?

How can I share 'global' application level context data between all objects living in an application. I'm thinking in terms of the currently logged on user record, which branch the user has opened to work on for a session, etc. How can I make this information available to all my forms and the classes they use for business logic services?

Just having one big global singleton AppContext object doesn't appeal to me, but I can't think of anything else right now. Maybe extend the Application class to offer a context service to all forms? I haven't worked on desktop apps for some time and have come to rely on e.g. the ever present Session object in ASP.NET.

Upvotes: 2

Views: 1489

Answers (2)

dana
dana

Reputation: 18155

I think the concept of a browser "session" was invented to maintain state across browser requests. That really isn't an issue for desktop apps. You could define a typed class with info about the user: id, email, name, etc. Basically whatever you would store in session. When someone logs in, create a new instance and assign it to a static variable. When they log out, set the static variable to null.

If you wanted it to behave more like HttpSessionState does (arbitrary key/value pairs), replace your typed class with a Hashtable.

EDIT

Depending on what you are planning to keep in session, my answer might vary, but here is a singleton-like class I quickly came up with.

public class AppContext
{
    private static AppContext current;

    // reference to the current app context
    public static AppContext Current
    {
        get { return current; }
    }

    // prevents new instance from being created externally
    private AppContext() { }

    // call when a user logs in
    public static void Login(AppUser user)
    {
        current = new AppContext()
        {
            ApppUser = user
        };
    }

    // call when a user logs out
    public static void Logout()
    {
        current = null;
    }

    // reference to the logged in user
    public AppUser User
    {
        get;
        private set;
    }

    public String FooString
    {
        get;
        set;
    }

    public int? FooInt
    {
        get;
        set;
    }

    public ComplexType FooClass
    {
        get;
        set;
    }

    public IList<Foo> ListOfFoo
    {
        get;
        set;
    }

    // ***** DEFINE ADDTL PARAMETERS HERE AS NEEDED *****
}

From any form in your application you could easily reference AppContext.Current. I am not sure if this quite answers your question, but this would be my first approach.

Upvotes: 1

Diego
Diego

Reputation: 18359

Server-client applications, such as Web-based ones, have to deal with data exchange across a network, which involves a lot of serialization and deserialization and keys to identify the user's context (such as a session id, client id, etc).

In WinForms, all objects are in memory and ready to be accessed at any point. This is simple and efficient and I wouldn't make it more complicated if requirements don't force me to.

An AppContext singleton seems perfectly reasonable to me, just watch for thread-safety issues if several windows are going to hit simultaneously.

Upvotes: 0

Related Questions