octobre
2009
AutoMapper est un outil permettant de définir une stratégie de mapping objet-objet.
Il peut être utilisé lorsqu’on a besoin de passer des objets entre des couches qui doivent être indépendantes, pour transformer des objets complexes en DTO ou inversement, etc …
Toutes ces opérations de transformation d’un objet A en objet B sont souvent redondantes, fastidieuses et sujettes à des erreurs.
Quoi de plus frustrant que de se rendre compte après moultes débuggages que si la nouvelle propriété n’est pas correcte c’est simplement parce qu’on a oublié de la mapper dans un assembleur perdu au fin fond de notre code ?
Tout ceci devient transparent grâce à automapper. Il est possible de définir des mappings automatiques entres objets.
Pour ce faire, AutoMapper se base le plus qu’il peut sur des conventions, les cas particuliers étant configurés par le développeur.
Par exemple, pour Mapper une Classe A en une Classe B de la sorte :
1: public class ClassA
2: {
3: public string Chaine { get; set; }
4: public int Entier { get; set; }
5: public long Long { get; set; }
6: }
7: public class ClassB
8: {
9: public string Chaine { get; set; }
10: public int Entier { get; set; }
11: public long Long { get; set; }
12: }
Il suffit simplement de faire :
1: Mapper.CreateMap<ClassA, ClassB>(); // défini le mapping
2: ClassB classB = Mapper.Map<ClassA, ClassB>(classA); // fait la conversion
Ici AutoMapper est assez malin pour se baser sur le nommage des propriétés et se rendre compte qu’ils sont équivalents dans les deux objets.
Rajoutons un champ aux deux classes, et il n’y a rien à changer dans le code effectuant la conversion !!
Si un nom ne correspond pas d’un objet à un autre :
1: public class ClassA
2: {
3: public long Long { get; set; }
4: }
5: public class ClassB
6: {
7: public long Valeur { get; set; }
8: }
Il est possible de l’indiquer à AutoMapper avec :
1: Mapper.CreateMap<ClassA, ClassB>()
2: .ForMember(dest => dest.Valeur, opt => opt.MapFrom(src => src.Long));
Il est également capable de traiter des objets complexes :
1: public class ClassA
2: {
3: public ClassC Obj { get; set; }
4: }
5: public class ClassB
6: {
7: public ClassD Obj { get; set; }
8: }
9:
10: public class ClassC
11: {
12: public int Val { get; set; }
13: }
14: public class ClassD
15: {
16: public int Val { get; set; }
17: }
Pour ce faire, il faut rajouter le mapping de la ClassC vers la ClassD :
1: Mapper.CreateMap<ClassA, ClassB>();
2: Mapper.CreateMap<ClassC, ClassD>();
AutoMapper est également capable de faire des conversions entre types à priori incompatibles.
1: public class ClassA
2: {
3: public string EnumValue{ get; set; }
4: }
5: public class ClassB
6: {
7: public EnumValue EnumValue { get; set; }
8: }
9:
10: public enum EnumValue
11: {
12: Val1 = 1,
13: Val2 = 2
14: }
en définissant un convertisseur :
1: ClassA classA = new ClassA { EnumValue = "Val2"};
2:
3: Mapper.CreateMap<ClassA, ClassB>();
4: Mapper.CreateMap<string, EnumValue>().ConvertUsing<EnumValueTypeConverter<EnumValue>>();
avec (par exemple) :
1: public class EnumValueTypeConverter<T> : ITypeConverter<string, T>
2: {
3: public T Convert(string source)
4: {
5: string foundedEnum = Enum.GetNames(typeof(T)).Where(e => string.Compare(e, source, StringComparison.InvariantCultureIgnoreCase) == 0).Single();
6: if (string.IsNullOrEmpty(foundedEnum))
7: throw new ArgumentException();
8: return (T)Enum.Parse(typeof(T), foundedEnum);
9: }
10: }
Retrouvez toutes les conversions/conventions sur le site d’AutoMapper.
Notons quand même que toutes ces conversions automatiques ont un coup au niveau de la performance. AutoMapper utilisant la réflexion pour effectuer ses mappings, il en résulte un peu plus de temps de conversion.
Pour moi, une excellente bibliothèque pour s’affranchir de code répétitif et succeptible de contenir des erreurs.
2 Commentaires + Ajouter un commentaire
Commentaires récents
- [Tests] Arrange Act Assert, une traduction ? dans
- [UnitTest][C#] Tester une méthode privée dans
- Récupérer une valeur d’un contrôle depuis une autre Form / inclusions croisées et déclaration anticipée dans
- Tutoriel : Utiliser la ListBox et l’Isolated Storage dans vos applications Windows Phone 7 avec Silverlight dans
- Tutoriel : Utiliser la ListBox et l’Isolated Storage dans vos applications Windows Phone 7 avec Silverlight dans
Archives
- janvier 2013
- avril 2012
- janvier 2012
- juin 2011
- janvier 2011
- décembre 2010
- novembre 2010
- septembre 2010
- juin 2010
- mars 2010
- février 2010
- janvier 2010
- décembre 2009
- novembre 2009
- octobre 2009
- septembre 2009
- août 2009
- juillet 2009
- mai 2009
- avril 2009
- mars 2009
- janvier 2009
- décembre 2008
- novembre 2008
- octobre 2008
- septembre 2008
- août 2008
- juillet 2008
- juin 2008
- mai 2008
- avril 2008
- mars 2008
- février 2008
- janvier 2008
- décembre 2007
- novembre 2007
- octobre 2007
- septembre 2007
- août 2007
- juillet 2007
- juin 2007
- mai 2007
je suis bien d’accord.
J’essaie de le faire adopter, mais chez moi on se montre très réticent dès qu’il y a un poil de reflexion.
Qui a dit que la réflexion c’était le mal ? :aie:
Zut, j’etais en train de preparer un post sur Automapper quand j’ai vu le tien
Donc, +1 pour la simplicité et la puissance de l’outil, je m’en sers pour mapper des DTO sur du subsonic, et pour le moment, la perte de perf est infime par rapport au gain en lisibilité