Mapping objet/relationnel .NET : tour d'horizon

Dans le monde Java, la pratique du mapping objet/relationnel semble beaucoup plus courante et plus industrialisée que dans le monde .Net, grâce entre autres au poids lourd Hibernate et à son intégration à des frameworks de plus haut niveau comme Grails.

Cet article a pour but d'analyser les raisons de la faible utilisation de la pratique du mapping objet/relationnel sur les projets à base de technologies Microsoft, ainsi que de présenter trois implémentations et leurs patterns associés.

De nombreux projets .Net utilisent encore des couches de persistances reposant sur ADO.Net, souvent produites par un générateur de code. Je vois deux causes à ce réflexe rarement optimal :

  • La fiabilité d'ADO.Net. Cette brique très importante du framework .Net est éprouvée et très courante sur le marché
  • Un phénomène de crainte devant l'inconnu que représente un framework auquel on doit déléguer un rôle aussi important ("comment verrai-je les requêtes qui seront envoyées au serveur ?", "La configuration est très compliquée, on va s'y perdre" sont les poncifs dans ce domaine)
  • Le manque de pédagogie autour des avantages plus profond que peut introduire un framework objet/relationnel, par exemple le Domain Driven Design
  • Le paradigm shift parfois violent vers la programmation orientée objet
  • L’absence de solutions provenant de Microsoft jusqu’à récemment

Pourtant, des alternatives natives .Net existent permettant un mapping objet/relationnel productif et industrialisé, ouvrant la porte à l'approche DDD sur les projets.

NHibernate

NHibernate est comme son nom l'indique le portage .Net de la référence Java du mapping o/r, Hibernate. Son implémentation suit son grand frère, avec comme souvent avec ce genre de projet, un léger temps de retard.

Malgré tout, NHibernate s'intègre fort bien à l'environnement .NET, avec utilisation des types natifs du framework et utilisation des fichiers de configuration natifs.

NHibernate permet une véritable abstraction entre domaine métier et logique de persistance. Par défaut, le développeur devra définir dans des fichiers dits de mapping la logique de persistance des classes de son domaine via une syntaxe XML très riche.

Certaines initiatives visent à simplifier/fiabiliser ces fichiers XML qui trainent une lourde réputation de difficulté à écrire et à maintenir chez les non-initiés. Entre autres, FluentNHibernate (Formulation du mapping sous forme de code .NET, donc impacté par un refactoring) et NHibernate.Mapping.Attributes (Attributs de décoration du modèle objet, équivalent des annotations Hibernate).

Pattern d'utilisation : le repository

PersonneRepository

Le pattern repository permet l’utilisation de NHibernate sans « polluer » le domaine objet par l’utilisation d’une classe exposant les méthodes classiques CRUD (GetAll, GetById…), ainsi que les méthodes plus personnalisées liées au comportement de persistance voulu.

ActiveRecord

ActiveRecords est une implémentation du pattern éponyme de Martin Fowler. Son implémentation est portée par le projet Castle, connu également pour son conteneur IoC. ActiveRecords repose sur NHibernate, auquel il apporte quelques simplifications d'implémentation, telles que la suppression des fichiers de mapping (les remplaçant par une décoration des classes par des attributs).

Pattern d'utilisation : l'active record

Personne Active RecordUn active record est une classe du domaine métier comprenant les comportements de persistance en base de données. ActiveRecord simplifie la création de telles classes par l'utilisation d'attributs .NET permettant de documenter à même le code de la classe sa logique de persistance. Tout cela de façon déclarative. Une classe de base, fournie par ActiveRecord, ajoute aux classes du domaine objet les méthodes classiques de CRUD (Save, SaveOrUpdate, GetById), le développeur n’ayant plus qu’à implémenter les méthodes personnalisées via l’implémentation de NHibernate sous-jacente.

Entity Framework

Entity Framework est la réponse de Microsoft à la popularité grandissante de NHibernate. Malgré des efforts significatifs dans le bon sens, plusieurs reproches lui ont été formulés par la communauté tels que :

  • Liaison trop forte entre un domaine métier et Entity Framework (nécessité d’implémenter des classes de bases et d’employer certaines classes pour les listes en lazy loading)
  • Outillage orienté « bottom up » (génération de modèle objet depuis une base existante) plutôt que « top down » (mapping vers une base d’un modèle objet préexistant)

Ces reproches ont été entendus par Microsoft, qui entend les résoudre pour la version 2 d’Entity Framework. Malgré tout, Entity Framework fournit une alternative à NHibernate fort bien outillée et intégrée à Visual Studio.

Pattern d’utilisation : l’object context

Le pattern d’utilisation d’EF suit celui de nhibernate, avec une classe responsable de persister et récupérer les objets depuis la base de données.

Et maintenant ?

Force est de constater que le mapping objet/relationnel .NET n'a plus à rougir devant la concurrence Java comme aux débuts de NHibernate. Malgré tout, l'adoption sur les projets est lente et mériterait un coup de pouce. L'attitude de Microsoft, en s'intéressant au sujet, prenant en compte les retours de la communauté sur Entity Framework, et communiquant sur le sujet, va certainement dans le bon sens. Esperons qu'Entity Framework 2 saura mieux concurrencer NHibernate et ActiveRecord afin d'obtenir une saine emulation dans ce domaine, qui serait bénéfique à la communauté.