NHibernate y ASP.NET MVC

NHibernate es la versión de Hibernate (Java) para .NET. Es una herramienta para el mapeo objecto-relacional que ayuda a identificar en nuestro código los atributos de una clase con las columnas de nuestras tablas, por decirlo de una forma simplificada.
El objetivo es que, para el programador, sea posible manejar su base de datos a través de los objetos de .NET, con lo que se consigue una mayor abstracción.
Podemos conseguir más información en la página oficial de la comunidad de usuarios. También tenemos a nuestra disposición el grupo de Google NHibernate-Hispano, donde podrán echarnos una mano con esta librería.

Para poder utilizarla, voy a comentar una serie de pasos a tener en cuenta para su configuración:

* Descargar la librería de NHibernate.
* Crear una clase para el manejo de sesión y configuración de NHibernate.
* Configuración en el archivo web.config.
* Creación de nuestros objetos de negocio.
* Creación de los archivos de mapeo.

DESCARGAR LA LIBRERÍA DE NHIBERNATE

En este post, vamos a trabajar con la versión NHibernate-2.1.0.GA. Para descargar la misma podemos hacerlo a través del siguiente enlace.

Como a día de hoy, nos encontramos en la versión ASP.NET MVC 1.0 y la 2.0 sigue estando en fase de desarrolo, vamos a utilizar la 1.0 para crear el ejemplo. Dicho esto, creamos un proyecto MVC (Si tenemos las dos versiones instaladas, se pueden diferenciar perfectamente ya que MVC 2.0 Preview 1 ó 2 tiene un 2 en el nombre de la plantilla).

Plantillas

En mi caso, voy a llamar a mi proyecto MovieManager. Confirmamos la creación del proyecto y lo primero que nos sugiere es crear un proyecto de Test. Aceptamos la sugerencia para poder utilizala más adelante 😀

Llegados a este punto, es necesario añadir una serie de referencias a nuestro proyecto. Descomprimimos el paquete que acabamos de descargar y añadimos las siguientes:

  •   NHibernate.dll
  •  Iesi.Collections.dll
  •  log4net.dll
  •  NHibernate.ByteCode.LinFu.dll

Cómo ya expliqué en un post anterior sobre la estructura de un proyecto ASP.NET MVC, tenemos tres partes bien diferenciadas: Modelo, Controlador, Vista(s). En este post, vamos a comenzar por la parte del modelo donde utilizaremos NHibernate.
En primer lugar, voy a crearme rápidamente una base de datos en SQL Server 2008 Express llamada MovieManager con una sola tabla por el momento.

CREAR UNA CLASE PARA EL MANEJO DE SESIÓN Y CONFIGURACIÓN DE NHIBERNATE

Cuando realizamos consultas a base de datos con NHibernate, es necesario controlar la sesión. A través del objeto session tenemos a nuestra disposición métodos como Save, Update, CreateCriteria, etc. Es muy importante manejar correctamente la sesión aunque espero poder hacerlo en algún post más adelante.

using NHibernate;
using NHibernate.Cfg;

namespace MovieManager.Models
{
    public sealed class Connection
    {
        private static ISessionFactory _sessionFactory;
        private static Configuration _nhConfig;
        private static ISession _session;

        public static ISession Session
        {
            get
            {
                if (_session == null)
                    GetCurrentSession();
                return _session;
            }
        }

        private static void Init()
        {
            _nhConfig = new Configuration();
            _nhConfig.AddAssembly("MovieManager");
            _sessionFactory = _nhConfig.BuildSessionFactory();

        }
        private static ISessionFactory GetSessionFactory()
        {
            if (_sessionFactory == null)
                Init();
            return _sessionFactory;
        }

        private static void GetCurrentSession()
        {
            _session = GetSessionFactory().OpenSession();
        }
    }
}

Actualizado 02/11/2009: Elimino los métodos innecesarios para este post en concreto. Mostraré en otro post diferente cómo sería la manera correcta de manejar la sesión y transacción de NHibernate.

CONFIGURACIÓN DEL ARCHIVO WEB.CONFIG

En el código anterior, teníamos una función Init() que se encargaba de cargar la configuración de NHibernate. Para que esto sea posible es necesario crear una sección en el web.config dónde configuramos todo lo relativo a la base de datos que queremos utilizar.

<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler,NHibernate" requirePermission="false"/>

Una vez declarada la sección, escribimos la misma con los valores necesarios para conectarnos a la base de datos oportuna:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider, NHibernate</property>
      <property name="connection.connection_string">
        Server=localhostsqlexpress;initial catalog=MovieManager;Integrated Security=true
      </property>
      <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
      <property name='proxyfactory.factory_class'>NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
    </session-factory>
</hibernate-configuration>

Actualizado 02/11/009 : Elimino la propiedad current_session_context_class, ya que por el momento no es necesario establecerla.

Existen varios dialectos soportados para poder utilizar distintos tipos de bases de datos. Para más información sobre ello, os facilito el siguiente enlace.

CREACIÓN DE NUESTROS OBJETOS DE NEGOCIO

La base de datos que tengo en mente almacena información sobre peliculas. Como hasta ahora solamente tenemos una tabla llamada Movies en nuestra base de datos, voy a crear la clase en .NET que representa a dicha tabla.

using System;

namespace MovieManager.Models.Objects
{
    public class Movie
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Genre { get; set; }
        public string Synopsis { get; set; }
        public DateTime Year { get; set; }
    }
}

La clase Movie, no contiene ningún método especial ni atributo que tenga relación con NHibernate. Ese rol, lo tiene el archivo de mapeo que será el que relacione cada propiedad de esta clase con la columna de una tabla específica.

CREACIÓN DE LOS ARCHIVOS DE MAPEO

Para crear el archivo de mapeo necesitamos saber, el nombre de la tabla, el nombre de la clase que representará en .NET a nuestra tabla y los campos que queremos recuperar de base de datos.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="MovieManager.Models.Objects.Movie,MovieManager" table="Movies" lazy="false">
    <id name="Id" column="Id" unsaved-value="0">
      <generator />
    </id>
    <property name="Name" column="Name" />
    <property name="Genre" column="Genre"/>
    <property name="Synopsis" column="Synopsis" />
    <property name="Year" column="Year" />
  </class>
</hibernate-mapping>

Hay que tener en cuenta un paso muy importante, a la par que olvidadizo 🙂 , y es lo siguiente: El archivo de mapeo debe tener la extensión .hbm.xml y, además, tenemos que asegurarnos de que el Action Build asignado a estos archivos de mapeo sea Embedded Resource ya que de no ser así la configuración de NHibernate no los tendrá en cuenta.

Con estos pasos, nuestra aplicación estaría lista para funcionar con NHibernate, ocupando la parte del Modelo. En el próximo post me centraré en la parte del controlador y vista para poder solicitar información al modelo y que el usuario pueda obtener a través de la vista los resultados recibidos.

¡Saludos!