Automapper est un "mappeur objet-objet" pour .Net, ce qui signifie copier des objets d'une classe dans une autre classe qui représente la même chose.
Pourquoi est-ce jamais utile? La duplication des classes est-elle jamais utile/bonne conception?
Une recherche rapide sur Google a révélé cet exemple:
http://www.codeproject.com/Articles/61629/AutoMapper
montrant une utilisation parfaitement valide d'AutoMapper qui n'est certainement pas un exemple de mauvaise conception. Dans une application en couches, vous pouvez avoir des objets dans vos données ou votre couche métier, et vous avez parfois besoin d'un sous-ensemble des attributs de ces objets de données, ou d'une sorte de vue pour eux dans votre couche d'interface utilisateur. Vous créez donc un modèle de vue qui contient des objets avec exactement les attributs dont vous avez besoin dans votre interface utilisateur, pas plus, et utilisez AutoMapper pour fournir le contenu de ces objets avec moins de code passe-partout.
Dans une telle situation, vos "objets de vue" ne sont pas un doublon de la classe d'origine. Ils ont différentes méthodes et peut-être quelques attributs en double. Mais c'est correct tant que vous n'utilisez ces objets de vue qu'à des fins d'affichage de l'interface utilisateur et ne commencez pas à les utiliser à mauvais escient pour la manipulation de données ou des opérations commerciales.
Un autre sujet que vous pouvez lire pour mieux comprendre ce sujet est le modèle Fowlers Command Query Responsibility Segregation , contrairement à CRUD. Il vous montre des situations où différents modèles d'objet pour interroger des données et les mettre à jour dans une base de données ont un sens. Ici, le mappage d'un modèle d'objet à un autre peut également être effectué par un outil comme AutoMapper.
La duplication des classes est-elle jamais utile/bonne conception?
Il est recommandé d'avoir une classe de modèle de vue distincte à utiliser dans la couche d'interface utilisateur plutôt que d'utiliser la même classe que celle utilisée dans la couche de données. Votre interface utilisateur/page Web peut avoir besoin d'afficher d'autres bits d'informations qui ne sont pas strictement liés à l'entité de données. En créant cette classe supplémentaire, vous vous donnez la liberté de modifier facilement votre interface utilisateur à mesure que les exigences changent avec le temps.
En ce qui concerne l'utilisation d'AutoMapper, je l'évite personnellement pour 3 raisons:
Échecs silencieux plus courants
Étant donné qu'AutoMapper mappe automatiquement entre les propriétés, la modification d'un nom de propriété sur une classe et non sur l'autre entraînera l'omission du mappage de propriétés. Le compilateur ne le saura pas. Automapper s'en fiche.
Manque d'analyse statique
On vous a donc donné une grande base de code à gérer. Il y a un million de classes avec un million de propriétés. Beaucoup semblent ne pas être utilisés ou sont des doublons. Cet outil "Rechercher toutes les références" dans Visual Studio vous aidera à voir où les propriétés sont utilisées et à construire une carte dans votre tête de la façon dont l'ensemble de l'application se tient. Mais attendez, il n'y a pas de références explicites à la moitié des propriétés car Automapper est utilisé. Mon travail est maintenant beaucoup plus difficile.
Exigences tardives qui augmentent la complexité
Automapper est très bien et dandy quand tout ce que vous voulez faire est de copier les valeurs d'une classe à une autre (comme c'est souvent le cas au début du développement), mais rappelez-vous ces exigences qui changent au fil du temps? Que se passe-t-il si vous avez maintenant besoin d'obtenir des valeurs d'autres parties de votre application, peut-être spécifiques à l'utilisateur connecté ou à un autre état contextuel?
Le modèle d'AutoMapper de création des mappages de classe un-à-un au démarrage de l'application ne se prête pas bien à ce type de changements spécifiques au contexte. Oui, il y a probablement des moyens de le faire fonctionner, mais je le trouve généralement plus propre, plus simple et plus expressif pour écrire la logique moi-même.
En résumé, avant de chercher Automapper pour vous épargner 30 secondes de mappage manuel d'une classe à une autre, pensez-y.
La programmation est l'art de dire à un autre humain ce que l'on veut que l'ordinateur fasse. - Donald Knuth
Dans cet esprit, demandez-vous "AutoMapper est-il utile aujourd'hui et sera-t-il demain?"
D'après mon expérience, lorsque quelqu'un s'est plaint de "trop de passe-partout" et souhaite utiliser AutoMapper, cela a été l'un des suivants:
Toutefois:
Si vous avez choisi une langue de type statique, profitez-en. Si vous essayez de contourner les contrôles dans le langage qui aident à éviter les erreurs dues à une utilisation excessive de la réflexion et des API magiques comme AutoMapper, cela signifie simplement que vous avez choisi un langage qui ne convient pas à vos besoins.
En outre, ce n'est pas parce que Microsoft a ajouté des fonctionnalités à C # qu'ils sont équitables dans toutes les situations ou qu'ils prennent en charge les meilleures pratiques. La réflexion et le mot-clé "dynamique", par exemple, devraient être utilisés dans les cas où vous ne pouvez tout simplement pas accomplir ce dont vous avez besoin sans eux. AutoMapper n'est pas une solution pour tout cas d'utilisation qui ne peut pas déjà être résolu sans lui.
Alors, la duplication des classes est-elle une mauvaise conception? Pas nécessairement.
AutoMapper est-il une mauvaise idée? Oui absolument.
L'utilisation d'AutoMapper indique des lacunes systémiques dans le projet. Si vous en avez besoin, arrêtez-vous et pensez à votre conception. Vous trouverez toujours une conception meilleure, plus lisible, plus facile à entretenir et sans bogues.
Il y a un problème plus profond ici: le fait que C # et Java insistent sur le fait que la plupart/tous les types doivent être distinguables par leur nom plutôt que par leur structure: par exemple class MyPoint2D
et class YourPoint2D
sont des types distincts même s'ils ont exactement les mêmes définitions. Lorsque le type que vous voulez est "une chose anonyme avec un champ x
et un champ y
" (c'est-à-dire un enregistrement), vous n'avez pas de chance. Donc, quand vous voulez transformer un YourPoint2D
dans une MyPoint2D
, vous avez trois options:
this.x = that.x; this.y = that.y
Le choix 1 est assez facile à petites doses mais devient rapidement une corvée lorsque le nombre de types à cartographier est important.
Le choix 2 n'est pas souhaitable, car vous devez maintenant ajouter une étape supplémentaire à votre processus de génération pour générer le code et vous assurer que toute l'équipe reçoit le mémo. Dans le pire des cas, vous devez également utiliser votre propre générateur de code ou système de modèles.
Cela vous laisse avec réflexion. Vous pouvez le faire vous-même ou utiliser AutoMapper.
Automapper est l'une de ces bibliothèques/outils où l'empereur court littéralement bout à bout. Lorsque vous dépassez le logo fastueux, vous vous rendez compte qu'il ne fait rien que vous ne pouvez pas faire manuellement avec de bien meilleurs résultats.
Bien que je ne sois pas entièrement sûr de la façon dont il suggère les membres de mappage automatique, cela implique très probablement une logique d'exécution supplémentaire et une réflexion possible. Cela peut être une pénalité de performance importante en échange d'un gain de temps. Le mappage manuel, en revanche, l'indication est exécutée bien avant la compilation.
Dans les cas où AutoMapper n'a aucun indice, vous devez configurer le mappage avec du code et définir des indicateurs. Si vous allez prendre la peine de faire tout le travail de configuration et de code, vous devez vous demander combien il économise par rapport au mappage manuel.