Windsor Container and NHibernate sessions
When developing MVVM WPF applications that use NHibernate as ORM one of the problems that you encounter is how to manage the sessions and keep the application fully testable.
I like using a Session per “screen” that in the MVVM world is equivalent to use “one Session per ViewModel”.
I also like to separate the presentation logic from the rest so I also create a Model for each ViewModel (even if this is not strictly necessary)
Finally the Model use one or more repository to access the database.
So, the NHibernate session is tied to the life of the Model and all the repositories that belongs the same model should share the same session so I can build transaction between repositories.
In addition to this I would like to inject the interfaces of the dependencies: the ViewModel will get the IModel, and the Model will get the IRepository1, IRepository2.
This picture should clarify the complete schema:
To create this scenario I choose Castle Windsor as a container and with the help of German Shuager, I defined this particular registration method:
public static void RegisterSharedWithFactory<TService>(Function<TService> factory) { _kernel.AddFacility<FactorySupportFacility>() .Register(Component.For<TService>() .UsingFactoryMethod(factory) .LifeStyle.Custom<ResolutionContextLifestyleManager>()); }
This method registers a component using a Factory method to create the instance since we cannot create an instance of the ISession but we must use a SessionFactory. Then sets the the lifestyle to a custom ResolutionContextLifestyleManager to be sure that in the same context the dependencies are created only once.
The implementation of ResolutionContextLifestyleManager is written by German and can be found here.
To understand what it does, consider this test:
[Fact] public void Two_Repo_In_The_Same_Model_Should_Have_Same_Session() { Container.Initialize(); Container.RegisterSharedWithFactory<ISession>(() => SessionHelper.OpenSession()); Container.Register<IRepo1, Repo1>(); Container.Register<IRepo2, Repo2>(); Container.Register<IModel1, Model1>(); IModel1 model1 = Container.Resolve<IModel1>(); Assert.Equal(model1.Repo1.Session, model1.Repo2.Session); // Repo1 and Repo2 shares the same session }
The model uses two repositories that uses the same instance of ISession exactly like in the picture above.
This configuration is very useful to manage the session in the right manner with NHibernate and Castle Windsor container and assure us the testability of all the components.
No commentsSearching with NHibernate
In these days, while working with NHibernate, I was building a method that load some data using an ICriteria and the Visual Studio 2008 Intellisense had show me a class named Example.
After a bit research throught the source code I understand it’s usage: this class enables your application to use a “partial-populated object” to build the where clause. Let’s see an example
Suppose that you need to load all Orders in state accepted at date 09/04/2007. You can write this code:
Order order = new Order();
order.Stato = OrderState.Accepted;
order.Date = new DateTime(2007, 04, 09);
ICriteria criteria = session.CreateCriteria(typeof(Order));
criteria.Add(Example.Create(order));
IList result = criteria.List();
What Nhibernate do is to parse all order’s property that have a non-default value and use that values to build a filter.
These method seems very useful to implement search functionality in your applcation.

RSS


