views:

728

answers:

6

Imagine in the Global.asax.cs file I had an instance class as a private field, lets say like this:

private MyClass _myClass = new MyClass();

and I had on Global a static method called GetMyClass() that gets the current HttpApplication and returns that instance.

public static MyClass GetMyClass()
{
    return ((Global)HttpContext.Current.ApplicationInstance)._myClass;
}

So I could get the instance on the current requests httpapplication by calling Global.GetMyClass().

Keep in mind that there is more than 1 (Global)HttpApplication. There is an HttpApplication for each request and they are pooled/shared, so in the truest sense it is not a real singleton. But it does follow the pattern to a degree.

So as the question asked, would you consider this at the very least the singleton pattern?

Would you say it should not be used? Would you discourage its use? Would you say its a possibly bad practice like a true singleton.

Could you see any problems that may arise from this type of usage scenario?

Or would you say its not a true singleton so its ok, and not bad practice. Would you recommend this as a semi quasi singleton where an instance per request is required? If not what other pattern/suggestion would you use/give?

Have you ever used anything such as this?

I have used this on past projects but I am unsure if its a practice I should stay away from. I have never had any issues in the past though.

Please give me your thoughts and opinions on this.

EDIT: I am not asking what a singleton is. And I consider a singleton bad practice when used imprperly which is in many many many cases. That is me. However, that is not what I am trying to discuss. I am trying to discuss THIS scenario I gave. Thanks.

+4  A: 

I'm not a .NET person so I'll refrain from commenting on this, except for this part:

Would you say its bad practice like a true singleton.

True singletons aren't 'bad practice'. They're HORRIBLY OVERUSED but that's not the same thing. I read something recently (can't remember where, alas) where someone pointed out the -- 'want or need' vs. 'can'.

"We only want one of these", or "we'll only need one": not a singleton.

"We CAN only have one of these": singleton

That is, if the very idea of having two of that object will break something in horrible and subtle ways, yes, use a singleton. This is true a lot more rarely than people think, hence the proliferation of singletons.

Cowan
By 'HORRIBLY OVERUSED' I assume you mean 'Incorrectly used in a lot of code and thus have a bad press for not being very good for a job they are not meant to be doing'.
Martin York
thats a good way to put it. I edited my post to make my stance a little clearer.
mattlant
By 'HORRIBLY OVERUSED' I mean used by people who just think 'oh, I only need one of these so I'll just stick it centrally and use static methods to access it', and then end up with inflexible, untestable code. The pattern's fine; using it 'cause 'static methods make it easy to get the object' isn't.
Cowan
Yes I agree. I just think it could be expressed in a better way :-)
Martin York
Just to add to this -- where I said "I read something recently", I realised today where it was, in case anyone cares. It was in Kevlin Henney's "Programmer's Dozen" talk at JAOO last week. He called it the "Highlander Rule" -- 'There can BE only one'
Cowan
+3  A: 

A Singleton is an object, of which, there CAN BE only one.

Objects of which there just happens to be one right now are not singleton.

James Curran
+3  A: 

Whether or not this fits the cookie-cutter pattern of a Singleton, it still suffers from the same problems as Singleton:

  • It is a static, concrete reference and cannot be substituted for separate behavior or stubbed/mocked during a test
  • You cannot subclass this and preserve this behavior, so it's quite easy to circumvent the singleton nature of this example
Ben Scheirman
Thanks, this is more the type of discussion/analysis I was looking for
mattlant
I marked this as the correct answer not because it was absolutely a correct answer, i dont htink this quesion has one, but you were one of the few who understood what i was trying to get at and gave some good input. thx again.
mattlant
A: 

I would say that it is defiantly NOT a singleton. Design patterns are most useful as definitions of common coding practices. When you talk about singletons, you are talking about an object where there is only one instance.

As you yourself have noted, there are multiple HttpApplications, so your code does not follow the design of a Singleton, and does not have the same side-effects.

For example, one might use a singleton to update currency exchange rates. If this person unknowingly used your example, they would fire up 7 instances to do the job that 'only one object' was meant to do.

Travis
+1  A: 

Forget singleton for a moment.

You have static methods that return application state. You better watch out.

If two threads access this shared state... boom. If you live on the webserver, your code will eventually be run in a multi-threaded context.

David B
Could you elaborate? That is the point of this question, to invoke discussion and analysis of the situation. Just saying watch out doesnt tell anyone anything and we cant learn from it.
mattlant
Thanks! I appreciate you updating it. I am unsure though as to how that might occur since each HttpApplication is run on a thread per request, so two threads shouldnt be accessing unless i explicitly created another thread. Maybe I am not clear on your meaning.
mattlant
+2  A: 

Since you're talking about a web application, you need to be very careful with assuming anything with static classes or this type of pseudo-singleton because as David B said, they are only shared across that thread. Where you will get in trouble is if IIS is configured to use more than one worker process (configured with the ill-named "Web-Garden" mode, but also the # worker processes can be set in machine.config). Assuming the box has more than one processor, whoever is trying to tweak it's performance is bound to turn this on.

A better pattern for this sort of thing is to use the HttpCache object. It is already thread-safe by nature, but what still catches most people is you object also needs to be thread-safe (since you're only going to probably create the instance and then read/write to a lot of its properties over time). Here's some skeleton code to give you an idea of what I'm talking about:

public SomeClassType SomeProperty
{
    get
    {
        if (HttpContext.Current.Cache["SomeKey"] == null)
        {
            HttpContext.Current.Cache.Add("SomeKey", new SomeClass(), null,
                              System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromDays(1),
                              CacheItemPriority.NotRemovable, null);
        }
        return (SomeClassType) HttpContext.Current.Cache["SomeKey"];
    }
}

Now if you think you might need a web farm (multi-server) scale path, then the above won't work as the application cache isn't shared across machines.

Kevin Dostalek
you bring up some interesting points, thankyou.
mattlant