Yeah. IIS is a web server. And when we inject code into its very guts like this, we have to account for the fact that multiple instances of said code are being run at any given time.
To pull off the fix for our original cavalier implementation, we must add a static flag and a mutex to theApplicationStartHandler class, using them in combination to ensure that the OnStart method is run once (and only once):
public abstract class ApplicationStartHandler : IHttpModule {
private readonly static object _mutex = new object();
private static bool _initialized = false;
protected abstract void OnStart();
public void Init(HttpApplication application) {
if (!_initialized)
lock (_mutex)
if (!_initialized)
Application_Start();
}
private void Application_Start() {
_initialized = true;
OnStart();
}
public void Dispose() { }
}
Our OnStart method will now indeed run once and only once when the HttpApplication starts up, with no Global.asax in sight. And because we were gentlemen about the whole abstracting thing, our consuming code (in this case, the ServiceStackStarter class above) need not change in response to this fix.
How to Approximate Application_Start in SharePoint Like a Gentleman [ Aptera ]