1

I am currently working on a WPF application using NHibernate as my persistence layer. I am trying to use MVVM, partially so that I can use Blend to help design my controls.

I am trying to follow Ayende Rahien's example in Effectus of having one ISession per presenter (except in my case it's a view model instead of a presenter). My view model looks something like this:

public abstract ViewModelBase : INotifyPropertyChanged
{
    private readonly ISessionFactory _sessionFactory;

    protected ViewModelBase(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;
    }

    private ISession Session
    {
        get
        {
            if (_session == null)
            {
                _session = _sessionFactory.OpenSession();
            }
            return _session;
        }
    }
    private ISession _session;

    // INotifyPropertyChanged implementation here...
}

public class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel(ISessionFactory sessionFactory)
        : base(sessionFactory)
    {
        var rep = new ProductRepository(this.Session);
        this.Products = new ObservableCollection<Product>(rep.GetAll());
    }

    public ObservableCollection<Product> Products
    {
        get
        {
            return _products;
        }
        set
        {
            if (_products != value)
            {
                _products = value;
                RaisePropertyChanged("Products");
            }
        }
    }
    private ObservableCollection<Product> _products;
}

public class DesignMainWindowViewModel : MainWindowViewModel
{
    public DesignMainWindowViewModel(ISessionFactory sessionFactory)
        : base(sessionFactory)
    {
    }

    public new ObservableCollection<Product> Products
    {
        get
        {
            List<Product> products = new List<Product>();
            // fill in design-time products...
            return products;
        }
        set
        {
        }
    }
}

What I would like to achieve is to have a ViewModelLocator that works with Unity to instantiate a design-time view model while working in Blend (and the regular view model when running the software normally). However, I need a design-time ISessionFactory in order to instantiate the DesignMainWindowViewModel.

Three questions:

  1. Is there an easy way to implement an in-memory ISessionFactory?
  2. Should I try to use an in-memory SQLite database?
  3. Am I taking the wrong approach to the whole thing?
Adam W. McKinley
  • 765
  • 8
  • 13
  • The view shouldn't know anything about NH. – Marcote Apr 02 '11 at 17:32
  • The view doesn't know anything about anything. I'm new to NHibernate, but I read that the best practice is to have one ISession per presenter, and I figured that it would follow to have one ISession per view model. What else do you suggest? – Adam W. McKinley Apr 02 '11 at 17:37
  • that ISession property in your ViewModelBase creates a dependecy between NH and the View. I don't think that is correct. – Marcote Apr 02 '11 at 17:40
  • I looked at Ayende's article which you linked to, and in his example he's using a pattern called Model-View-Presenter. If you download the code sample he provides and look in the AbstractPresenter, you'll see the example I am basing my code on. In Ayende's use of MVP, each presenter has its own ISessionFactory. This is exactly what I'm doing, except I have a view model (which, again, is not the view) instead of a presenter. Do you happen to know of an example where someone is using a design-time DataContext in a WPF or Silverlight application which uses NHibernate for persistance? – Adam W. McKinley Apr 02 '11 at 18:01
  • I'm not sure about the design-time thing, but we are finishing a Winforms/WPF hybrid app using the following approach. we have a base class called BaseModel which basically handles the NH session in a similar way what you are doing with the ViewModelBase. the ViewModel know this BaseModel classes. The lifetime of the BaseModel is tied to the ViewModel (if the user closes the forms, disposes the ViewModel, hence disposing the BaseModel with it's session). Basically we push down your approach a little in your architecture. Anyway, there's no silver bullet. – Marcote Apr 02 '11 at 18:13
  • (cont.) This works for us, because the screens have a very clear lifetime, this is not always the case in every app. Check the examples in unNHAddins, they are very good. – Marcote Apr 02 '11 at 18:14

1 Answers1

2

The view shouldn't know anything about NH. Is not it's responsability. NH Session should be handled at Service level or Repository Level. There are some many variables and approches and truth is this: there is no silver bullet. All the depends of what the View is doing.

I suggest looking at some examples in unNHAddins (http://code.google.com/p/unhaddins/) dealing with NH and WPF.

I added more information in this answer yesterday: NHibernate in C# application, how to manage session

Good luck!

Community
  • 1
  • 1
Marcote
  • 2,977
  • 1
  • 25
  • 24