Sunday, December 20, 2009

Castle: PerWebRequestLifeStyle revisited

In my previous post I talked about a problem using Castle project’s Inversion of Control container (MicroKernel and/or Windsor) during application initialization.

Today I’ve finally had a chance to dive into this subject and see if I can come up with a solution.

A workaround
Testing has shown that moving all initialization to the Application’s Init method seems to resolve this issue at runtime. I’ve tried this on my development system and on an Windows 2008/IIS7 server.

UPDATE: This workaround may cause problems because the HttpApplication.Init method is invoked when ever a new application instance is created. 
Since there can be more than one instance of the HttpApplication within an AppDomain the Init method may be invoked more than once and from multiple threads concurrently causing all kinds of nasty problems.

In contrast Application_Start is invoked once for the entire lifetime of the AppDomain in which the application runs so that is the place to do application configuration without worrying about multi-threading issues.

Components using PerWebRequestLifeStyle (PWR for short) will never work from Application_Start because at that point in the ASP.NET application lifecycle modules are not initialized yet. I’ve tried to figure out a way to make the module used by PWR work, but as far as I can tell there isn’t any. Not without breaking compatibility with Medium-trust anyway.

Note that it’s perfectly ok to create the container and register services with it from Application_Start, just don’t try and resolve any components that use the PWR life style.

Also note that this is no solution for testing an application outside of ASP.NET. For that the hybrid solution I’ve described in my previous post is still a valid solution.


dbones said...

(have you fixed this? as it looks like you did not do another follow up post)

I have PWR working in my MVC2 app.

1. Add the required in the web.config
2. in the App start, create then call a function to register all the components, trans, Singleton and PWR

done, it will now inject the dependences

I think I may be missing the point.

ps, for IIS7 you have to register it twice

Marnix said...

@dbones Yes, you're missing the point. PWR works ok, but breaks when used during initialization or when running outside a web context, for example in unit tests.
This means that it's not possible to use components with PWR-lifestyle to initialize the application before the first request is handled.
Note that I have successfully deployed several applications using the fix I described in my previous post on this topic (i.e. with a hybrid lifestyle that falls back to transient for scenarios where PWR doesn't work)