27

Web application initialization is as follows:

  1. As we know when IIS receives the first request for a particular Asp.net application resource, IIS creates an instance of a HttpApplication (defined in global.asax codebehind).
  2. When this new instance is created it's initialization happens that also checks all configured HTTP modules.
  3. All modules are then instantiated and put in the application's Modules collection (of type HttpModuleCollection)
  4. modules are looped through and their Init() method is called (when they register for request events)

As far as I understand it the above scenario happens when a web application is started/initialized (hence application start event).

What happens with modules?

Are they (re)instatiated on each request or reused from the Modules property on each consecutive request while the web application is alive? As I understand IIS and Asp.net they are reused through the whole life of a web application.

If they are reused, can we assume that their Init() method is actually a pseudo event handler for application start event? The thing is we can't attach to application level events within http modules. But if they are being reused we could use Init() as application start event and do whatever we'd put in global.asax instead.

Question

Can we assume that module's Init() method is called only on application start event? Could we use this assumption to i.e. register routes for applications whose global.asax codebehind we can't change? web.config is usually accessible and we can change it the way we want.
Would this actually work?

Additional info

We can check HttpApplication code and check its InitModulesCommon() method. This one actually calls Init() of each registered HTTP module. What is more interesting is that this method is only used by InitIntegratedModules() and InitModules() methods. Which are both used only in HttpApplication.InitInternal() method. This is the basis of my assumptions, but I would like to know whether someone has abused IHttpModule.Init() for application start event.

Robert Koritnik
  • 97,460
  • 50
  • 267
  • 388

2 Answers2

33

Init() is called only once (per HttpApplication instance)

After I tested this the inner workings of IHttpModule initialization are as follows:

  1. Every IHttpModule is initialized at web application start by instatiating and a call to Init() method
  2. HttpApplication stores all module instances in its Modules property
  3. Modules are then reused for the whole life of an HttpApplication and are not discarded/reinitialized as long as the application is alive

So the best outcome is

You can't attach an IHttpModule to application level events, but you can use its Init() method as pseudo application start event delegate. Inside it you can execute any code that you'd usually put inside Application_Start delegate in your Global.asax.

You can also read detailed information about it in my blog post.

But be careful in real-life web server environment

But IIS uses something called application pools. And each pool can have an arbitrary number of HttpApplication instances. Yes multiple. Application starting creates all these instances. Every one of them initializes their own list of modules but only the first one executes the Application_OnStart event handler.

So whenever your module modifies some common shared resource, you should take extra measures to indicate that the first module has done that and others won't do it again. Read an additional blog post about it that will show you how and when to use thread locking with your module to make it actually act as an Application_OnStart event handler. BTW: It's also possible to handle Application_OnEnd event if you need to. ;)

Detailed blog post links

  1. Writing a custom IHttpModule that handles Application_OnStart event
  2. How to correctly use IHttpModule to handle Application_OnStart event
Robert Koritnik
  • 97,460
  • 50
  • 267
  • 388
  • 8
    @MatteS: Misleading in what way? It's perfectly correct, because `Init` is called only once per every `HttpApplication` instance. When one reads through the whole answer (as they should) then they understand how to approach their own problem. – Robert Koritnik Jun 29 '11 at 06:39
  • 1
    I am not sure why but the solution you have provided in your blog does not work for me, I receive the error below: [NullReferenceException: Object reference not set to an instance of an object.] System.Web.PipelineModuleStepContainer.GetEventCount(RequestNotification notification, Boolean isPostEvent) +30 System.Web.PipelineStepManager.ResumeSteps(Exception error) +408 If I remove the "applicationStarted" variable from the function logic, the website loads fine. I am currently using IIS 8.5, .NET 4.5.1 and Integrated pipelines. Would you have any idea why? Thank you – IMR Apr 18 '15 at 22:01
  • @RobertKoritnik do you know if these happen in one go: "instatiating and a call to Init()"? i.e. I am mostly wondering if the module instance is created *after* the application instance. – eglasius Nov 19 '18 at 08:54
3

Application_Start is only run once for the lifetime of your application.

IHttpModule.Init is run for each instance of HttpApplication, before request processing begins. See the walkthrough. Init is where you can register events used to process the request.

An instance of HttpApplication can be reused for multiple requests. ASP.Net pools HttpApplication objects, so the Init will be called once for every new instance of HttpApplication

matt-dot-net
  • 4,186
  • 18
  • 24
  • The link you provided doesn't say when `Init()` gets called. And based on `HttpApplication`'s code I've examined it doesn't look that modules would be reinstantiated for each request. This is a very basic example of a module that you provided that doesn't give any insight in the actual execution pipeline. – Robert Koritnik Jul 30 '10 at 14:56
  • Check my additional info. It will give you a better insight into this *issue*. – Robert Koritnik Jul 30 '10 at 15:10
  • Exactly! So `Init()` method of a `HttpModule` can be thought of an application start event then. Just as I anticipated. I don't think developers actually realize that or think of it when developing apps. Still it's impossible to get to Session events within `HttpModule`. – Robert Koritnik Jul 30 '10 at 19:44
  • Init does act as an application start event. It would be better to say as an Application init event. Only the first instance also executes `Application_OnStart`. But that can as well be done by a module. You have to use this whenever your module modifies common shared resource. Read all the details in my blog post. http://erraticdev.blogspot.com/2011/01/how-to-correctly-use-ihttpmodule-to.html – Robert Koritnik Jan 24 '11 at 08:32