Apr 7, 2007

dynamically hookup (hard code in global.asax) HTTP Modules

one issue that has come up a few times is that the root site defines an HTTP module. The child virtual (an off the root virtual directory) when created by default inherits that module entry in web.config and usually fails because the module isn't available. Now it's easy to use a remove entry in your virtuals:

add the following to your web.config file
remove name="TopLevelModule"

and that can usually take care of it. However, if you have many sub-virtuals you need to touch this can get tedious.
So rather than fixing the Web.config in each subapplication I've removed the module definition in web.config and instead load the module via code. HttpModules hook up to the HttpApplication object of an ASP.NET application which is represented by your global.asax file in a Web project. HttpModules hook up to the events of this HttpApplication object, and since all a module really does is attach to the appropriate event handler in its Init() method there's no reason that you can't do this in code as well.
There's one little gotcha though: It has to be done at just the right time in the HttpApplication life cycle which is when the HttpApplication object initializes (multiple times, once for each instance of HttpApplication). The only method where this works correct is HttpApplication Init().
To hook up a module via code you can run code like the following instead of the HttpModule definition in web.config:

public class Global : System.Web.HttpApplication
{
public static xrnsToashxMappingModule Module = new xrnsToashxMappingModule();

public override void Init()
{
base.Init();
Module.Init(this);
}
}

All you do is override the HttpApplication's Init() method and then access the static instance's Init method. Init() of the module hooks up the event and off you go.
Note the use of HttpApplication Init; you might be tempted to use Application_Start, but that event is more like a static constructor that fires only once per Web application. Init() fires everytime a new application instance is initialized. Remember there are multiple HttpApplication instances executing side by side to handle simultaneous requests and each instance initializes separately.
Using web.config is the preferred way of hooking up handles usually though for sure. But there are situations where you might not want to allow the module hookup to be dynamic. For example, if you have an application where the module is crucial to operation, performs some security feature, or version check, you might not want to allow removal of the module - this way it's a lot more difficult to disconnect the module. If you have a packaged application it can also be nice to have the set up hard coded in this fashion - one less thing to screw up during installation or when users start poking around in configuration files

kick it on DotNetKicks.com

1 comment: