Archive

Articles taggués ‘Model First’

Entity Framework Model First

J’ai eu l’occasion d’intervenir sur un projet utilisant Entity Framework 4.1 avec une approche Model First. Je profite de ce billet pour faire part de mes premiers retours.

Contexte technique du projet

  • une trentaine d’entités, dont une dizaine stéréotypées référentiel
  • des règles métier
  • un workflow de validation
  • une approche domain driven

Rappels sur les principes de l’approche Model First

Je ne vais pas détailler ces rappels car il existe de nombreux articles sur le sujet. Je vous propose celui-ci qui me parait intéressant.

Dans les grandes lignes, le processus de développement consiste en deux étapes :

  1. définition d’un modèle du domaine, appelé modèle conceptuel dans Entity Framework. Cette définition est généralement réalisée à partir d’un designer graphique, outil permettant de créer visuellement un pseudo diagramme de classes. Pour les plus courageux (ou quand l’outil a atteint ses limites), il est également possible de modifier le fichier XML sous-jacent. Mais soyons clairs : le fichier de mapping XML de NHibernate est peu complexe par rapport au fichier EDMX proposé par EF !
  2. transformations de modèles. A partir du modèle conceptuel, EF nous propose des outils permettant de générer les modèles relationnels et objets ainsi qu’une partie de la couche d’accès aux données. Ces transformations reposent sur les T4 Text Templates, outil simple et efficace de génération de code.

Quelques principes adoptés sur le projet

  • Domain driven : un modèle du domaine riche, contraint, contenant notamment les règles métier.
  • L’IHM, réalisée avec ASP.NET Web forms et jQuery n’a alors en théorie plus qu’à venir se greffer sur le modèle
  • patterns context-per-request et conversation utilisée dans seam
  • utilisation partielle du scaffolding pour les entités de référence

Avantages

  • Outillage productif intégré dans Visual Studio
  • Adaptation de la génération avec les T4Templates. Voici un exemple d’adaptation : partant du principe qu’une contrainte sur le domaine apporte de la richesse et évite des erreurs d’incohérence, j’insiste sur le fait de marquer les contraintes. Si une entité Livre a nécessairement un titre, le constructeur de Livre devrait avoir un paramètre non optionnel « titre » et la visibilité du setter de la propriété « Titre » devrait être réduite. Quelques lignes dans le T4Template et cette règle est généralisée à l’ensemble du domaine !

    Relation ManyToOne requise

    Relation ManyToOne requise

  • Refactor facilité : Approche agile, permettant de refactorer pour améliorer la sémantique du domaine et donc sa compréhension. Le travail à réaliser est opéré sur le modèle conceptuel. Domaine, repository, schéma de BD sont générés : ça ne coute donc presque rien. Un peu de rework est parfois nécessaire dans les couches supérieures, en fonction du refactor apporté.

Limites rencontrées

  • Mécanisme de Facets non extensible. Les Facets permettent d’apporter des précisions sur les propriétés des entités : par exemple si la propriété est Nullable, sa longueur maximale… Certaines facets sont manquantes, typiquement la facet unique. Certes, les équipes de Microsoft travaille dessus, mais je doute qu’ils puissent couvrir tous les cas de figures. Ce qui je pense pourrait être intéressant, serait introduire un point d’extension permettant aux développeurs de définir de nouvelles Facets. Les développeurs pourraient alors exploiter ces Facets dans les templates.
  • Méta données des entités non extensibles. Certaines entités jouent des rôles particuliers, nécessitant une implémentation qui leur est propre. C’est par exemple le cas des entités de référence (les unité de mesure, les catégories de produits, …). Ces entités ont une particularité : les interfaces d’administration sont des interfaces de type CRUD. Le scaffolding est une bonne option pour ce type d’interface. Pour l’activer, il faut tagguer les classes C#. Je trouve dommage qu’on ne puisse pas tagguer ces entités directement dans le modèle avec une annotation custom. Dans l’exemple, l’annotation aurait été Referential. Dans la transformation de modèle, on aurait alors pu rajouter une règle : toutes les entités stéréotypées Referential supportent le scaffolding. A défaut, nous avons utiliser le mécanisme des classes partielles pour apporter cette information. 
  • Stratégie d’héritage globale : il existe plusieurs stratégies pour mapper un héritage objet dans un modèle relationnel (table par type, table par classe concrète, table par hiérarchie). Le choix d’une stratégie doit être traitée au cas par cas : dois-je privilégier la performance sur une requête polymorphe ? dois-je promouvoir le faible couplage ? Malheureusement dans l’outil, le choix est unique pour tout le modèle :(. La encore, un mécanisme d’extension de type stéréotype aurait été le bienvenu.
  • Namespace globale. Actuellement avec l’outil, on ne peut définir qu’un seul Namespace pour un modèle EDMX.

Ma conclusion

Je trouve cette approche productive pour des projets nécessitant peu de spécificités (comprendre sortir du cadre prévu par Microsoft) et dont la complexité du modèle du domaine reste raisonnable. Comme toutes les approches Model Driven, la modification des templates n’est intéressante que si le nombre d’entités est significatif . La limite majeure pour des projets plus conséquents, c’est le manque de points d’extension. Je terminerai par un dernier constat qui est également vrai pour les outils de ce type : ne pas se laisser berner par la facilité apparente !

Categories: .NET Tags: ,