Friday, June 25, 2010

Hybrid lifestyles in Windsor

All Inversion of Control (IoC) containers offer some way to control the lifecycle or scope of the component instances. Singleton (one instance per container) and Transient (a new instance each time your request it from the container) are the two most common scopes.

Castle Windsor calls these scopes "lifestyles" (the term "lifecycle" is used for something else) and it comes with these built-in lifestyles (I'll just quote the documentation):

  • Singleton (default): one instance per container
  • Transient: a new instance each time your request it from the container
  • PerThread: one instance per thread
  • PerWebRequest: one instance per HttpContext (HTTP request)
  • Pooled: instances will be pooled to avoid unnecessary constructions

More importantly, a custom lifestyle manager can be plugged-in, just by implementing the ILifestyleManager interface. Some examples of this are the WCF facility PerWcfSession and PerWcfOperation lifestyles and the PerHttpApplication lifestyle I implemented to inject dependencies to HttpModules.

There are other lifestyles that come in handy sometimes, especially in web applications. I created the Castle.Windsor.Lifestyles contrib project to host them. I have implemented these lifestyles so far:

  • Abstract hybrid lifestyle
  • Abstract hybrid PerWebRequest + X
  • Hybrid PerWebRequest + Transient
  • PerWebSession: one instance per HTTP session
  • PerHttpApplication (mentioned above)

An hybrid lifestyle is one that actually blends two underlying lifestyles: a main lifestyle and a secondary lifestyle. The hybrid lifestyle first tries to use the main lifestyle; if it's unavailable for some reason, it uses the secondary lifestyle. This is commonly used with PerWebRequest as the main lifestyle: if the HTTP context is available, it's used as the scope for the component instance; otherwise the secondary lifestyle is used.

The PerWebSession has a couple of caveats:

  • Components using this lifestyle have to be serializable if you're using a session-state mode other than InProc.
  • Components using this lifestyle will not be properly released, since the session end event only fires when using the InProc session-state mode.

Usage:

  1. Add a reference to Castle.Windsor.Lifestyles.dll
  2. Use the appropriate lifestyle descriptor in your registration, e.g.:

    container.Register(Component.For<SomeService>()

                    .LifeStyle.HybridPerWebRequestTransient());

3 comments:

Leniel Maccaferri said...

Dear Mauricio,

With this post you helped me solve the problem I describe here:

http://www.leniel.net/2013/01/signalr-ondisconnected-task-and-dependency-injection-with-castle.windsor-hybrid-lifestyle.html


Thank once again,

Leniel

Anonymous said...

Good job. Your package are very helpful.

Mihir said...

+1 - @mihirvinchhi