9.48 Windsor Tutorial - Part Seven - Lifestyles

优质
小牛编辑
128浏览
2023-12-01

We noted in a previous part the ISession object from NHibernate is our Unit of Work. What that means in practical terms, is that in the context of a web request we want to have just one. Also every web request will have a different instance. Then when the web request ends we will dispose of the session thus flushing all the changes to the database.

Lifestyles

In Windsor the sharing of objects is called lifestyle. If you recall, when we were registering controllers we specified that their lifestyle is Transient. That means that the instance is never shared, and is not bound to any context. Every time we request a transient component we get a new instance. Also transient components that were explicitly Resolved have to be explicitly Released, since Windsor has no idea when their lifetime should end.

In a previous part when we registered ISessionFactory and ISession we didn't specify any lifestyle. If the lifestyle is not defined, the default of singleton will be used. Singleton means that there is going to be just a single instance in the entire container, for as long as the container is alive (which means - entire lifetime of the application, since that's how long we use the container).

For singleton components an instance is created upon the first request for the component, and then reused for every subsequent request. It is destroyed only when the container gets Disposed. This is exactly what we want for ISessionFactory. That's one of the first things you learn about NHibernate - ISessionFactory is big, heavyweight, thread-safe, and you only should ever have one per database.

That's great - all fine there.

That's however as far as we can get for what we want from ISession. When it's a singleton our changes will never be flushed, hence they'll get lost, instead of getting persisted at the end of request. Also ISession is not thread safe so we'll be exposed to multiple bugs if multiple requests try to access it. Also as we get more and more requests, its internal cache will grow and grow, getting slower with every request until we run out of memory. To fix this we have to change its lifestyle to PerWebRequest.

The PerWebRequest lifestyle

To change the ISession lifestyle to be per web request, we need to specify that in the registration. So we need to change it to the following:

Kernel.Register(
    Component.For<ISession>()
        .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
        .LifestylePerWebRequest()
);

Now Windsor will call our factory method once in every web request where it needs an ISession instance and then reuse this instance in the scope of that web request. When a new web request comes along, the factory method will be called again, asking ISessionFactory to OpenSession for that new web request, and so on.

:warning: Releasing components: Some contexts, like web request have a well defined ends that Windsor can detect. Therefore Windsor knows when to release the per web request objects and it will do it without requiring any action from you. That's not the case for all lifestyles however. This brings us to the Release method.

A rather detailed discussion about releasing components can be found in this blog post. It is highly recommended that you read it

:information_source: Importance of lifestyles: Getting lifestyles right when using Windsor (or any other container) is one of the most important aspects of working with a container, and one that has has big impact on your application. Pay attention to what lifestyle you assign to your components. There's no hard and fast rule on which one you should chose so think how the components will be used.

Summary

One of the most important concepts regarding Inversion of Control containers is the lifetime or lifestyle of the components that are registered within them, which this section discussed. Ensure you understand the concepts, because they are fundamental to using Windsor. Another important part of any IoC container is managing dependencies, which you can read about in Part Eight - Satisfying Dependencies.