On a souvent besoin de copier les propriétés d'un objet en mémoire vers un autre, y compris entre des objets de types différents. (Si cette première phrase vous semble être en Na'vi, la suite confortera cette impression). En mode "quick win", un petit bout de code qui recopie une par une les propriétés fonctionne très bien.
Oui, ça marche, mais, las, le résultat est fragile : vous le savez très bien, un jour quelqu'un, peut-être vous un vendredi soir à 21h (ah non pas vous), va ajouter une propriété sur ces objets et oublier d'ajouter aussi une ligne dans cette méthode de recopie. S'en suivra peu à peu la faillite du système : une corruption de la base de données, des transactions financières aberrantes, votre nom dans les journaux et un milliard d'Euros à rembourser de votre poche. La loi de Murphy n'aide pas, mais si vous aidez la loi de Murphy... Et encore je ne parle même pas d'une mise en production le 21 décembre 2012...
Bref dans le cas présent le quick win est un big loss pour qui intègre le futur dans sa vision du monde.
Vous allez me dire que vous travaillez en mode Agile (pas Agile à la sauce Coué, mais le vrai mode Agile, celui qui se donne des moyens) et que vos tests unitaires vous protègent. C'est tant mieux, mais si la vérification de la copie des objets est elle aussi manuelle, la nouvelle propriété ne sera probablement pas testée -- on a oublié de modifier la méthode, pourquoi penserait-on au test unitaire associé ? Et si jamais votre test est solide parce que vous avez eu la bonne idée d'utiliser les APIs de reflection pour l'implémenter, il est probable que vous allez employer la même ruse pour implémenter la méthode de recopie...
Bref, simplifiez-vous la vie, réinventez d'abord la roue parce que c'est amusant et formateur, puis choisissez un outil spécialisé qui marche mieux que le vôtre (désolé).
Emit Mapper est un de ces outils, et les premiers tests le présentent comme 400 fois plus rapide (mais voir § ci-dessous) que son concurrent Automapper parce qu'il s'appuie sur la librairie Emit (code de recopie généré une seule fois) plutôt que sur les API de Reflection (chaque copie va déclencher les mêmes appels aux méthodes de reflection, quoiqu'il y a des astuces à connaitre).
Attention : comme l'a fait remarquer Romain dans les commentaires, Automapper utilise aussi Emit (depuis aout 2009). Peut-être que le benchmark date un peu, peut-être que l'auteur est optimiste (mais cf. ci-dessous). Le chiffre 400 est donc à prendre avec le doute et le recul d'un scientifique qui lit une boîte de Chocapic. Si l'un de vous a le courage de comparer...
Deuxième mise à jour : Vladimir Romanko, l'auteur d'Emit Mapper, vient d'expliquer dans les commentaires les raisons de cette différence impressionnante de performance. Il précise aussi que les benchmarks ont été écrits de façon impartiale, et que les mesures sont faciles à reproduire puisque les benchmarks font partie des sources.
Emit mapper fonctionne sous .Net, Mono et Silverlight. Il vient de sortir en version 1.0 sur Codeplex
Les commentaires récents