I've gone rounds with this ever since I started programming classic ASP 12 (or so) years ago and I've never found a great solution because the architecture of ASP and ASP.NET has always been a swamp of bad practices, magic shared singletons, etc. My biggest issue is with the HttpApplication
object with its non-event events (Application_Start
, Application_End
, etc.).
If you want to do stuff once for the entire lifespan of an HTTP application, Application_Start
is the obvious place to do it. Right? Not exactly. Firstly, this is not an event per se, it's a magic naming convention that, when followed, causes the method to be called once per AppDomain created by IIS.
Besides magic naming conventions being a horrible practice, I've started to think it might be a reason there exist no such thing as a Start
event on the HttpApplication
object. So I've experimented with events that do exist, such as Init
. Well, this isn't really an event either, it's an overridable method, which is the next best thing.
It seems that the Init()
method is called for every instantiation of an HttpApplication
object, which happens a lot more than once per AppDomain. This means that I might as well just put my startup logic inside the HttpApplication
object's constructor.
Now my question is, why shouldn't I put my startup logic in the constructor? Why does even Init()
exist and do I need to care about Application_Start
? If I do, can anyone explain why there is no proper event or overridable method for this pseudo-event in the HttpApplication
object?
And can anyone explain to me why in a typical ASP.NET application, 8 instances of my HttpApplication
are created (which causes the constructor and Init
to run just as many times, of course; this can be mitigated with locking and a shared static boolean called initialized
) when my application only has a single AppDomain?
Calling Application_Start the first time an instance of HttpApplication is created, but not on subsequent instances seems a bit of a hack. Perhaps Microsoft didn't want to explain the concept of a static constructor to people who didn't really want to know.
Application_End(), however, seems to be a necessity, as there is no C# equivalent of a static destructor/finalizer. As hacks go, this isn't that bad. It just smells a little funny.