Classes et methodes partielles avec .Net 3.5


D’apparence simplistes, les classes et les méthodes partielles apportent un renouveau inattendu aux scénarios de générations de code.

Voici un lien vers un article que j’ai écrit sur le sujet: http://msdn2.microsoft.com/fr-fr/vcsharp/bb968892.aspx

Mitsu


Comments (6)

  1. Jb Evain says:

    Bonjour,

    «Les méthodes partielles viennent enrichir les possibilités des classes partielles en répondant à des scénarii de programmation par aspect (AOP).»

    C’est inexact. Je rappelle que le but de l’AOP est de permettre le développement de composants techniques réutilisables, sans que le code applicatif n’est à souffrir de «porter» explicitement ce code.

    Prenons un exemple d’extension methods mal utilisées à des «fins d’AOP»:

    //

    partial void StartTransaction ();

    partial void EndTransaction ();

    partial void LogMessage (string s, params object [] p);

    public void Track (Person p) {

    LogMessage ("Track Person P: {0}", p);

    StartTransaction ();

    LogMessage ("Start new Transaction");

    system.Set (p);

    EndTransaction ();

    LogMessage ("Transaction commited");

    LogMessage ("Person {0} tracked", p);

    }

    //

    Bien sur on peut ne pas implémenter LogMessage ou le gestionnaire de transaction. Il reste que le code applicatif, est mélangé avec du code technique. Et c’est le but premier de l’AOP d’éviter ça.

    D’autant plus qu’avec ce système d’extension methods, la réutilisation du code n’est pas vraiment possible. Comme vous le dites, la méthode doit être privée à la classe. Et c’est le second but de l’AOP de permettre facilement la réutilisation du code.

    Donc non, on ne fait pas d’AOP avec les extension methods. 🙂

    C’est marrant, parce que je me souviens avoir entendu le même genre de trucs avec les classes partielles quand elles sont apparues:

    http://evain.net/blog/articles/2005/04/25/the-module-a-new-design-pattern

    C’est dommage, le reste de l’article est très bien, et insiste bien sur le fait que les extension methods sont seulement un moyen d’influencer sur du code généré.

  2. Les partial methods c’est bien mais ça ne résout pas tous les problèmes. Je pense notamment à la possibilité de rajouter des attributs sur une méthode dans un autre fichier de la classe partielle que tu as évoqué (=> obligation d’encapsuler la propriété pour rajouter un attribut).

    Sinon les partial methods permettent de faire des trucs assez rigolos et relativement inattendu si on n’a pas bien compris le principe, très bien expliqué dans ton article d’ailleurs, que la méthode n’existe pas tant qu’elle n’est pas redéfinie : choisir par réflexion quelle méthode appeler. C’est ce qui est fait, par exemple, par la classe System.Data.Linq.ChangeDirector.StandardChangeDirector dans la méthode Delete (appelée sur le SubmitChanges du DataContext) :

    internal override int Delete(TrackedObject item)

    {

       if (item.Type.Table.DeleteMethod == null)

       {

           return this.DynamicDelete(item);

       }

       try

       {

           item.Type.Table.DeleteMethod.Invoke(this.context, new object[] { item.Current });

       }

       catch (TargetInvocationException exception)

       {

           if (exception.InnerException != null)

           {

               throw exception.InnerException;

           }

           throw;

       }

       return 1;

    }

  3. Mitsu Furuta says:

    Hé hé, je m’attendais à ce genre de critique.

    Je réfute pourtant. L’AOP ne date pas d’hier. Ce n’est pas une techno, c’est un concept.

    Même si les implémentations actuelles utilisent l’injection post compilation, l’AOP est avant tout un moyen de séparer les concepts. Il ne me semble pas avoir déjà lu qu’un usage LOCAL dans lequel un code appelle une méthode sans en connaitre son existance physique ne peut pas prétendre être de l’aspect.

    Je n’ai pas dit que les méthodes et classes partielles étaient des solutions d’AOP mais "répondaient à des scénarii de programmation par aspect".

  4. Jb Evain says:

    «l’AOP est avant tout un moyen de séparer les concepts. Il ne me semble pas avoir déjà lu qu’un usage LOCAL dans lequel un code appelle une méthode sans en connaitre son existance physique ne peut pas prétendre être de l’aspect.»

    Marrant, dans la première phrase, vous définissez le but de l’AOP, et dans l’autre, vous contredisez ce que vous venez de dire. Puisque l’usage est LOCAL, et qu’on appelle directement du code transverse, il n’y a par définition pas de séparation des concepts, ou du moins pas plus que ce que l’OOP traditionnel de .net fourni. Que la méthode soit partielle ou pas.

    Et c’est là l’anti-thèse de l’AOP, qui comme vous le dites, vise à séparer les domaines techniques.

    Notons que je reste dans le domain de l’AOP en tant que concept, et non pas de ses implémentations sur .net.

    Et donc dire que les méthodes partielles «répondent à des scénarii de programmation par aspect», c’est faux. Parce que le seul et unique but des méthodes partielles est d’affiner le comportement de code généré, par le biais de code utilisateur qui appartient au même domaine technique que le code généré.

    Si l’AOP ne date pas d’hier, il est souvent mal compris. D’où ma motivation à ne pas favoriser la confusion.

  5. Mitsu Furuta says:

    JB, j’ai très bien compris ce que tu voulais dire.

    J’avoue chipoter un peu mais même si l’on est dans le même domaine, il a une séparation conceptuelle très intéressante: dans le cas du code généré par Linq to Sql par exemple, la personne qui a pensé le générateur et les méthodes partielles générées n’a aucune idée de qui va l’utiliser/l’implémenter au final. C’est juste ce point que je voulais mettre en avant.

    Encore une fois, je n’ai pas dit que les méthodes et classes partielles étaient des solutions d’AOP, j’ai juste comparé des scénarii qui étaient très proches.