Accueil Nos publications Blog Améliorer votre productivité avec Fody

Améliorer votre productivité avec Fody

FodyLa manipulation du code IL d’une assembly durant l’étape de compilation nécessite une quantité très importante de code à mettre en place. Et cela exige des compétences très fortes en MSBuild ainsi que les API de Visual Studio.

Fody est une librairie gratuite et open source, développée par Simon Cropp qui se base sur des concepts de programmation orientée aspect AOP en utilisant la libraire Mono.Cecil dans le but d’éliminer toute la complexité de code qu’on peut avoir pour faire une manipulation simple dans le code IL.

.

IL : Intermediate Language
CIL : Common Intermediate Language
MSIL : Microsoft Intermediate Language

Avant d’entrer dans les détails de Fody, je vous rappelle que ces trois termes représentent la même chose (le code le plus bas niveau généré par les Frameworks .NET et Mono). Et pour ne pas créer une confusion aux lecteurs, je vais utiliser le mot IL dans la suite de cet article.

En fait, quand on compile un code écrit avec n’importe quel language (VB.NET, C#, J# ou F#) ce code n’est pas converti directement en bytecode mais en IL code. Seulement une partie de l’IL code nécessaire au moment de l’exécution est convertie en bytecode.

Par exemple, pour une méthode simple comme celle-ci :


    public int Add(int x, int y)
    {
    return x + y;
    }
    

Le code IL qui sera généré par le compilateur est le suivant :


    .method public hidebysig instance int32 Add(int32 x, int32 y) cil managed
    {
    .maxstack 2
    ldarg.0
    ldarg.1
    add
    ret
    }
    

L’instruction ldard permet de lire et de stocker la valeur lue dans la pile à la position x fournie en argument, add fait l’addition des valeur stockées et finalement ret va retourner la valeur calculée.

Ce code représente, dans la majorité des cas, les .dll et les .exe qu’on utilise tous les jours.

Étapes de compilation

Compilation

Chaque langage possède son propre compilateur, ce dernier est responsable de la compilation (transformation) du code source vers le code IL, sans tenir compte de l’architecture de la machine. Le code IL sera ensuite compilé soit par le JIT (Just in time compilation) ou par Ngen (Native Image Generator) afin d’être exécuté, mais cette fois en tenant compte de l’architecture de la machine.

Heureusement, le code IL peut être manipulé pendant la phase de compilation, durant laquelle on peut injecter d’autres instructions afin d’ajouter des fonctionnalités supplémentaires au code initial. Cela permet par exemple de :

  • Gérer les logs et les exceptions
  • Ajouter des null guard
  • Modifier le comportement des méthodes standards

Exemple d’utilisation avec INotifyPropertyChanged

Si vous créez des applications en WPF, Silverlight, WP8/W8 ou plutôt si vous êtes développeur .NET 😉 il est fréquent que l’on ait besoin d’implémenter l’interface INotifyPropertyChanged. Cette dernière va de permettre à la vue (View) de se rafraichir en cas d’un changement dans le Model ou le ViewModel afin de charger les nouvelles données.

On ajoutant l’attribut ImplementPropertyChanged, de la manière suivante, à notre classe Model :


    [ImplementPropertyChanged]
    public class PersonModel
    {
    public string Nom { get; set; }

    [DoNotNotify]
    public string Prenom { get; set; }
    }
    

Fody va automatiquement injecter le code nécessaire pour l’implémentation de l’interface INotifyPropertedChanged. Quand on ouvre la dll générée, on remarque que notre classe est devenue comme ça :


    public class PersonModel : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;
    public virtual void OnPropertyChanged(string propertyName)
    {
    PropertyChangedEventHandler changedEventHandler = PropertyChanged;
    if (changedEventHandler == null)
    return;

    changedEventHandler(this, new PropertyChangedEventArgs(propertyName));
    }

    public string Nom
    {
    get { return this.<Nom>k__BackingField; }
    set
    {
    if (string.Equals(this.<Nom>k__BackingField, value))
    return;

    this.<Nom>k__BackingField = value;
    OnPropertyChanged("Nom");
    }
    }

    public string Prenom { get; set; }
    }
    

Information supplémentaire :

Fody va automatiquement rendre toutes les propriétés de classe notifiables, sauf si on ajoute de manière explicite l’attribut DoNotNotify à la propriété en question.

Dernier mot

Fody ne permet pas seulement d’implémenter INotifyPropertyChanged, on peut même développer nos propres plugins avec cette librairie, qui compte actuellement une cinquantaine.

J’ai implémenté Fody.PropertyChanged dans une Portable Class Library en utilisant un pattern MVVM, puis j’ai créé une application Windows Phone 8 utilisant cette librairie. afin d’illustrer son fonctionnement. Le code source est téléchargeable ici.