views:

612

answers:

3

I am unsure about the scope of one static inner class of a non-static class.

In the lines below, would the variable DataContextCreator.Instance (part of a Singleton pattern) point to the same PDataContext instance for all Page objects/page requests or would each object have its own instance?

public class Page : System.Web.UI.Page
{

    private class DataContextCreator
    {
        static DataContextCreator() { }

        public static readonly PDataContext Instance = new PDataContext(TUtil.GetConnectionString());
    }

    public PDataContext DataContext
    {
        get
        {
            return DataContextCreator.Instance;
        }
    }
}

Do I have to work with HttpContext.Current for this to work in the desired way, i.e. no shared DataContext? If so, is there another way?

I am not sure whether modifying the static class to private (as I have done) does the trick.

Thanks!

EDIT: This is my solution where I now have the same lazy-loading capability but without static variables. I don't think I need to put a mutex lock around the holding variable in this case.

    private PDataContext _DataContext;
    private PDataContext DataContext
    {
        get
        {
            if (this._DataContext == null)
            {
                this._DataContext = new PDataContext(TUtil.GetConnectionString());
            }
            return this._DataContext;
        }
    }
+2  A: 

It would be the same for every page. A static variable is a static variable, however nested it is. (Generics make things "interesting" in that a static variable in Foo<int> is separate to the one in Foo<string> etc, but that's not relevant here.)

If you want to make something depend on the instance of the Page, it needs to be an instance variable within Page. (I'd advise against naming a case the same as its base class, by the way.)

Jon Skeet
Thank you. I just now see that it would be easy to do this with an instance variable. I came from the singleton pattern. But that is not required here.
And yes and I do not usually name the derived class after the base class. It is an existing class and was done by someone else. Maybe not too late to change that.
Maybe someone could take a quick look at my solution in the latest edit and post if there are any problems with it.
The new code seems reasonable so long as only one thread is going to be using the instance.
Jon Skeet
+1  A: 

Nested classes are purely for naming convenience (and some modifier changes (private etc)). They are actually the same as regular (top-level) classes in terms of behaviour. So Instance is shared completely (it is not tied to an Page instance).

Marc Gravell
+1  A: 

As the Instance variable is static, it only exists once, so all threads share the same value. Putting the variable in another class doesn't change how a static variable works.

To make a singleton that is local to the page instance, you would store the reference in the page context:

public PDataContext DataContext {
   get {
      PDataContext result = HttpContext.Current["PData"];
      if (result == null) {
         result = new PDataContext(TUtil.GetConnectionString());
         HttpContext.Current["PData"] = result;
      }
      return result;
   }
}
Guffa