mercredi 3 octobre 2012

Automapper, un framework qu'il est bien ! mais ...

Je viens de livrer un petit projet où j'ai utilisé automapper et il m'a économisé des centaines de lignes de code.

Si ce Framework est vraiment très pratique, et installable rapidement avec NuGet, il m’a cependant déçu par sa documentation, pauvre voire inexistante. Il n’y a qu’à télécharger les sources pour s’en convaincre : https://github.com/AutoMapper/AutoMapper ; pas la moindre doc Xml en entête des classes et méthodes, walou, pour un Framework aussi plébiscité, ça fait cheap !

La documentation de base recommande l’utilisation de la classe statique “Mapper” pour configurer et exécuter le mapping et sans vouloir jouer les rabat joie, ça fait pas très objet tout ça. De plus j’ai eu le besoin d’avoir plusieurs “profiles” de configuration à ma disposition et Google pour une fois ne m’a pas vraiment aidé, c’est uniquement en regardant les sources que j’ai trouvé le truc.

Donc voici, pour avoir plusieurs mappers configurés différemment (et injectable en plus !), le code :

public class ClassA
{
public ClassA() { ClassBs = new HashSet<ClassB>(); }
public int Id { get; set; }
public string Prop1 { get; set; }
public ICollection<ClassB> ClassBs { get; set; }
}

public class ClassB
{
public int Id { get; set; }
public string Prop2 { get; set; }
}

public class ConfigTest : MappingEngine
{
static readonly ConfigurationStore _configurationStore;
static ConfigTest()
{
_configurationStore = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers());

_configurationStore.CreateMap<ClassA, ClassB>()
.ForMember(e => e.Prop2, conf => conf.MapFrom(a => a.Prop1))
;
}

public ConfigTest() : base(_configurationStore) { }
}


Prenez exemple sur l’objet ConfigTest pour avoir un mapper personalisé, instanciable, tout bien comme il faut.



Un autre besoin sur automapper m’a demandé beaucoup moins de temps de recherche : faire en sorte de filtrer un collection pour que tous ses éléments ne soient pas reproduits.



public class ConfigFilter : MappingEngine
{
static readonly ConfigurationStore _configurationStore;
static ConfigFilter()
{
_configurationStore = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers());

_configurationStore.CreateMap<ClassA, ClassA>()
//http://stackoverflow.com/questions/6226419/using-automapper-to-apply-a-filter-to-a-collection
.ForMember(e => e.ClassBs, conf => conf.MapFrom(a => a.ClassBs.Where(b => b.Id % 2 == 0)))
;
}

public ConfigFilter() : base(_configurationStore) { }
}


Enjoy :-), n’hésitez pas à vous servir de ce Framework, une fois les interrogations de config passée, c’est que du bonheur, et n’oublier pas de faire appel à la méthode “AssertConfigurationIsValid()” du “ConfigurationProvider” dans vos tests unitaires, sans quoi vous pourriez vous retrouver avec une propriété non mappée lors de la maintenance de l’application, un oubli est si vite arrivé.

Aucun commentaire: