Introduction
When you write the following code:
var fooOne = container.Resolve<IFoo>();
var fooTwo = container.Resolve<IFoo>();
// do something useful
container.Release(fooOne);
container.Release(fooTwo);
What will happen? Will
fooOne and
fooTwo reference the same object? Or will Windsor give you two separate objects? What happens when you call
Release? The answer is - it depends. The behavior is controlled by something called the lifestyle of your components.
Release behavior is also controlled by IReleasePolicy
The statement about releasing above is true with the assumption that
Release Policy of your container tracks the instances of the component.
Standard lifestyles¶
Out of the box Windsor provides set of lifestyles you can use (as defined by
LifestyleType enum)
Singleton
Just a single instance per container will be created, the first time the component is requested from the container. All subsequent calls will return the same instance. Releasing singleton component does nothing. Component will be released when the container it's registered with is disposed.
Default
Singleton is the default lifestyle, which will be use if you don't specify any explicitly.
Transient
Each time a component is requested a new instance will be created. Releasing transient component releases it immediately.
Transient components are tracked by the container
To ensure proper components lifecycle management Windsor will track your components, even transient ones. That means that unless you release them, Garbage Collector will not be able to reclaim them, and you'll end up with de-facto memory leak. Remember to release your transient components. Read more about
release policy.
PerThread
Instance of a component will be shared in scope of a single thread of execution. It will be created the first time the component is requested on given thread. Releasing the component explicitly does nothing. Instances will be released when the container they're registered with is disposed.
PerWebRequest
Instance of a component will be shared in scope of a single web request. The instance will be created the first time it's requested in scope of the web request. Releasing it explicitly does nothing. Instance will be released upon the end of the web request.
Registering PerWebRequestLifestyleModule
In order to function properly per web request requires a
IHttpModule -
Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule to be registered in your web.config:
<httpModules>
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor"/>
</httpModules>
if you're running on IIS7 you may need to register it in
system.webServer/modules section instead.
<configuration>
<system.webServer>
<modules>
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
</modules>
</system.webServer>
</configuration>
Pooled
A pool of instances will be created, and then one of them will be returned when requested. Poolable lifestyle has two parameters that influence its behavior -
initialSize and
maxSize.
When the component is first requested the pool of
initialSize elements is instantiated and single one of them is marked internally as
in use and returned. When more components are requested pool will first return all of the components it has that are not
in use, and if it runs of it will start creating new ones. Releasing the components may do either of two things. In case when the pool has more components
in use than
maxSize the component will be released immediately . Otherwise the component will be recycled (if it implements
IRecyclable) and returned to the pool marked as
ready to use.
The IRecyclable interface
Windsor provides special interface -
Castle.Core.IRecyclable for poolable components. It contains single method:
void Recycle();
This method is invoked when the component is returned to the pool, and components can use it to implement custom initialization/clean up logic.
Custom
Allows you to set your own implementation of
ILifestyleManager for the component. Also used be some facilities, like WCF Facility which provides two additional lifestyles - per WCF session and per WCF operation.
Setting lifestyle
Via code
Fluent registration API exposes methods for setting lifestyle.
Via XML
It is also possible to set lifestyle from
XML configuration.
Via Attributes
Windsor provides set of attributes that you can use to set suggested lifestyle for your components.
Prefer other solutions
Lifetime attributes are targeted at low level components, that extend the container itself. For your domain services, it's better to use any of the other approaches, so that you don't need to reference the container in your domain.
[Singleton]
[Transient]
[PerWebRequest]
[PerThread]
[Pooled(2, 5)]
[CustomLifestyle(typeof(MyLifestyleHandler))]
Attributes are for defaults
The attributes denote suggested lifestyle for the component. You can override it by specifying other lifestyle explicitly from fluent API, or XML configuration.