Logo

NHibernate

The object-relational mapper for .NET

Nhibernate and WPF: The core


Part I: Introducing NHiberate and WPF: The ChinookMediaManager

Introduction


This is my second post about the Chinook Media Manager, an example application for NHibernate and WPF. In this post I will outline some concepts behind the architecture that I’ve chosen.

Note

Probably at some points you will feel that this is over-architected, YAGNI and so on. Yes, you are right I’m not trying to bind a grid to a collection of objects there are tons of samples on the net about that subject.

The four musketeers

The core of the application is composed of four components:

  • ChinookMediaManager.Data: Contains the definition of repositories interfaces.
  • ChinookMediaManager.DataImpl: Contains the implementation of these repositories plus other nhibernate things that we will need to make work the implementation of repositories (like mappings).
  • ChinookMediaManager.Domain: Contains the domain classes plus model interfaces (we will focus on this concept latter)
  • ChinookMediaManager.DomainImpl: Contains the implementation of the models.

My base repository definition is as follows:

public interface IRepository<T> : IQueryable<T>
    {
        T Get(object id);
        T Load(object id);
        T MakePersistent(T entity);
        void Refresh(T entity);
        void MakeTransient(T entity);
    }

This means that a repository is a IQueryable<T> by itself and we can build queries in a more natural way.
I have seen a lot of repositories implementations with methods Save, Update and Delete, there is nothing wrong with it, just that I think that MakePersistent (Save) and MakeTransient (Delete) better represents that functionality (I have stolen this terminology from a Gustavo Ringel’s example).
You could find the implementation here.

Don’t touch “the domain”

Working with WPF sometimes you will need that your entities implement INotifyPropertyChanged or IEditableObject for data binding. Although the implementation of those interfaces is simple, if you implement directly in your domain you will tie your domain to a presentation concern and also will end writing a lot of code.

So, I wrote an addin for nhibernate (unhaddins.wpf) that will help you to inject those behaviors without touching anything in your domain model. 

We only have to add the entity to the container as follows:

container.Register(Component.For<Album>()
    .NhibernateEntity()
    .AddNotificableBehavior()
    .LifeStyle.Transient);

If you need to add editable object behavior (read this and this) you simple put “.AddEditableBehavior()”.
If we want a transient instance we will request it to the container (or an object factory). In unhaddins we have got an artifact that allows nhibernate to instantiate entities from the container, read this post from Fabio Maulo.

For INotifyCollectionChanged, unhaddins.wpf has a Collection Type Factory, we need to configure NHibernate as follows:

nhConfiguration.Properties[Environment.CollectionTypeFactoryClass] =
  typeof (WpfCollectionTypeFactory).AssemblyQualifiedName;

With this simple step all bag, sets and list (more coming up) of objects retrieved from NHibernate will implement INotifyCollectionChanged.

It goes without saying that this configuration is not in the domain.

As you can see, I don’t have to put presentations concerns inside “the four musketeers”.

In the next post I will talk about models and CpBT.


Posted Sat, 15 August 2009 03:30:52 PM by jfromainello
Filed under: AOP, Session, WPF

comments powered by Disqus
© NHibernate Community 2024