MVC et NHibernate

MVC vous laisse choisir la meilleure voie pour votre projet de stocker et récupérer un modele de données. Nous utilisons NHIBERNATE parce que c’est l’ORM le plus mature en .NET et il est basé sur un projet Java mûr : HIBERNATE.
Il y a une quantité remarquable de documentation en ligne et gratuite associée à NHIBERNATE et sa performance (exécution) et la fiabilité est sans égal.

NHibernate n’est pas votre seule option. « LINQ to SQL » est aussi populairement appareillé avec MVC. C’est une structure rapide et facile pour vous faire commencer. Quoi que commençant avec NHIBERNATE soient un peu plus d’exigence initialement, le compromis d’apprendre qu’ORM plus robuste dépassera rapidement cet investissement initial.

NHibernate est très flexible, mais nous utiliserons seulement une petite fraction de sa puissance dans cet article. Pour une couverture plus en profondeur, je suggère de lire le livre « NHibernate in Action » (http://www.lirmm.fr/~gouaich/upload/books/Manning%20NHibernate%20in%20Action.pdf), parce qu’il couvre la partie caching, batching et l’utilisation de query avancée en utilisant le Langage d’interrogation (HQL : Hibernate Query Langage).

Quand utiliser Active REcord, Query Object, ou le Repository Pattern ?

Il y a plusieurs manières pour une application de mettre en oeuvre la persistance. Active
Record, Query Object, et Repository sont parmi les design pattern les plus communs utilisés dans le développement logiciel d’entreprise. Tous ces modèles sont décrits plus en détail dans le livre : « Patterns of Enterprise Application Architecture » par « Martin Fowler ».
Le Repository pattern isole le code d’accès de données en créant une couche de classes pour traduire en arrière au code d’application. Les avantages du Repository est que ce dernier met une séparation claire entre la logique d’application et le code d’accès d’ORM/Base de données. Le Repository a été popularisé plus récemment par le « Ruby on Rails ». Au lieu d’utiliser les Repository classes pour encapsuler le code d’ORM, il utilise les classes modèles eux-mêmes pour gérer l’accès de données. NHibernate peut aussi être configuré pour utiliser l’Active Record pattern.
Query Object est un pattern qui propage un certain nombre de petites classes légères qui contiennent des Query complexes. Cela peut empêcher votre Repository ou Active Record objects de devenir trop grand mais encore plus important peut encourager la réutilisation des query.

Je vous encourage à utiliser le Repository pattern parce qu’il est plus simple à comprendre, c’est aussi le plus courament utilisé dans des applications web .NET. Le Repository pattern isole le code d’accés au données en créant une couche de classes pour traduire en code applicatif. Il vous donne une place pour mettre le code qui traite avec n’importe quelles optimisations d’accès de données ou bizarreries qui peuvent aborder en utilisant un ORM. Dans ASP.NET MVC, la classe de Repository manipule l’accès de données et la classe de contrôleur coordonne la requête d’un utilisateur.

Utilisation du Repository Pattern :

Ce modèle garde notre code d’accès de données dans un jeu discret d’objets.
Cela nous laisse tester notre code d’ORM indépendamment de notre code de contrôleur.

Avant d’utiliser le Repository Pattern on a besoin de configurer NHibernate pour qu’il fonctionne avec notre base de données.
Pour cela nous utiliserons Fluent NHIBERNATE, un projet qui aide à simplifier la configuration et le mapping des classe pour NHIBERNATE.

Configuration de NHibernate Fluently :

D’abord nous créerons une deuxième instance de base de données pour exécuter nos tests de Repository. Cela protège l’autre instance d’être écrasé comme nous exécutons des tests de Repository.

La chose suivante à faire est créent un nouveau projet de test pour holder notre persistance appelé « Test.Persistance » .
Vous devrez télécharger et ajouter des références à la dernière copie de fichiers binaires NHIBERNATE Fluient. N’oubliez pas d’ajouter une référence au projet Web parce que c’est où les Repository et le code de configuration auront leurs cycle de vie.
À l’intérieur de notre projet Web, nous allons devoir ajouter un répertoire appelé Persistence. C’est où nous stockerons des classes liées à la connexion et à la configuration pour NHIBERNATE. Nous créerons aussi le sous-répertoire « Repositories » pour tenir les classes Repository pour notre projet. Nous ajouterons encore un sous-répertoire appelé « ClassMaps » pour tenir nos fichiers database-to-class mapping, mapping avec Fluent NHibernate.
Créons la class NHibernateConfiguration pour tenir les informations de configuration :

using System;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Tool.hbm2ddl;
 
 namespace GetOrganized.Persistence
 {
 public class NHibernateConfiguration
 {
 public static ISessionFactory SessionFactory { get; private set; }
 
public static void Init(IPersistenceConfigurer databaseConfig,
 Action<Configuration> schemaConfiguration)
 {
 SessionFactory = Fluently.Configure()
 .Database(
 databaseConfig)
 .Mappings(m => m.FluentMappings.
 AddFromAssemblyOf<NHibernateConfiguration>())
 .ExposeConfiguration(schemaConfiguration)
 .BuildSessionFactory();
 }
 
 public static ISession CreateAndOpenSession()
 {
 return SessionFactory.OpenSession();
 }
 }
 }

NHibernateConfiguration sera utilisé tant par le test que par le code de production, mais avant que nous puissions initialiser SessionFactory utile, nous devrons dresser le mapping de quelques classes à la base de données.

Mapping avec Fluent NHibernate :

Pour qu’un ORM fasse son travail, il a besoin d’instructions comment vos objets mappent les tables de votre base de données. La façon la plus simple de le faire est l’automapping.
L’automapping peut être configurée pour chercher un namespaces spécifique pour que seulement vos modeles de classes réelles soient mappés.
Cela empêche des classes de contrôleur, par exemple, d’être mappé à la base de données. L’automapping fonctionne en matchant des data type .NET au type de données équivalent pour la base de données. Par exemple, l’Entier .NET Int32 se traduirait aux données int dans le Serveur SQL. L’ajout d’automapping à votre configuration Fluent NHIBERNATE est aussi simple que l’ajoutant du code suivant à notre Fluently.Configure() dans NHibernateConfiguration :

var model = AutoMap.AddFromAssemblyOf<NHibernateConfiguration>()
.Where(t => t.Namespace == "GetOrganized.Models" );
var configuration = Fluently.Configure()
.Database(databaseConfig)
.Mappings(m => m.AutoMappings.Add(model));
configuration.BuildSessionFactory();

Cependant, l’automapping vous prendra seulement jusqu’ici, comme quand vous devez spécifier des relations spécifiques et des types de données. C’est pourquoi nous travaillerons avec des classe maps. Traditionnellement ces maps existent autant que fichiers XML, un pour chaque classe. Notre classe Todo aurait un fichier XML incorporé appelé « Todo-mapping.xml ».
Fluent NHibernate nous permet de mapper des classes en utilisant des classes C# qui hérite de la class « ClassMap ».
L’utilisation des classes C# pour mapper rend plus facile la vérification des erreurs de syntaxe et rend aussi la navigation des class map files plus faciles.
On va stocker tous nos maps dans un repertoire « Persistence/ClassMaps ».
Mappont Todo en utilisant Fluent NHibernate :

using FluentNHibernate.Mapping;
using GetOrganized.Models;
 
 namespace GetOrganized.Persistence.ClassMaps
 {
 public class TodoMap : ClassMap<Todo>
 {
 public TodoMap()
 {
 Id(x => x.Title);
 Map(x => x.Completed);
 Map(x => x.Outcome);
 References(x => x.Topic).ForeignKey().Not.LazyLoad();
 }
 }
 }

Comme vous avez vu, Fluent NHIBERNATE rend le mapping facile…

Kamel DJELLAL
Chef de projet
EDIS CONSULTING – GROUPE UBISIDE

http://www.ubiside.fr/