Dot.Blog

C#, XAML, WinUI, WPF, Android, MAUI, IoT, IA, ChatGPT, Prompt Engineering

Entity Framework et la compatibilité arrière (problème Datetime2).

[new:05/07/2010]Vous possédez un OS récent, comme Windows 7, vous développez avec les outils les plus modernes (disons VS 2010 au hasard) et, bien entendu votre base de données installée en local est SQL Server 2008. D’une part parce que c’est une bonne version, mais surtout parce que vous n’avez pas trop le choix… Vous créez une application pour un client qui utilise SQL Server 2005 et là, pof! dès qu’il exécute votre logiciel il y a une exception du genre “The version of SQL Server in use does not support datatype 'datetime2”… Plus...

Silverlight 4 : Localiser une application

[new:19/06/2010] L’informatique suit le monde, et le monde se mondialise… Une entreprise française devient une filiale d’un fond de pension américain, une éditeur de logiciel de Toulouse fusionne avec concurrent catalan, etc.. Les outils eux-mêmes se globalisent, prenez Phone 7 ou le prochain Eee Pad d’Asus sous Windows 7, pensez au Market Place centralisé de Microsoft pour vendre vos applications. Les applications ne peuvent plus se contenter d’être purement locales, elles doivent intégrer dès leur création les mécanismes permettant de les localiser. Le Framework lui-même, à la différence des plateformes précédentes, gère la localisation de façon naturelle et intégrée. Nous allons voir dans ce billet comment rendre vos applications Silverlight utilisables dans le monde entier. Plus...

NDepend 3 : votre code est une base de données en or…

[new:10/6/2010]NDepend est un outil très intelligent dont je vous ai déjà parlé (voir le billet Visual NDepend un outil d'analyse de code original et puissant ainsi que l’allusion directe qui y est faite dans Le retour du spaghetti vengeur). La version 3 est désormais totalement intégrée à l’IDE de VS 2010 ce qui rend son utilisation encore plus simple, directe et rapide. NDepend transforme votre code en une mine d’or ! Tout code, projet, solution devient une base de données qui peut être interrogée et obtenir une vision totalement neuve sur ses forces … et ses défauts !Plus...

Article ! Le Binding Xaml, sa syntaxe, éviter ses pièges… (WPF/Silverlight)

imagePromis dans mon dernier billet, le voici enfin ! Ce nouvel article dédié au binding Xaml pèse 77 pages (le record était tenu jusqu’à lors par mon article M-V-VM avec Silverlight avec 70 pages) et se présente sous la forme d’un PDF et de 9 projets exemples.

Le binding cet inconnu … J’en parlais dans mon billet Le retour du spaghetti vengeur, le binding avec sa syntaxe pleine d’accolades et de chaînes de caractères non contrôlées à la compilation est un piège à bugs et la porte ouverte au code spaghetti.

Plutôt que de me lamenter et vous laisser vous embourber dans la sauce de ces spaghetti là, j’ai pris ma plume, et voici le résultat : 77 pages sur le binding Xaml, son fonctionnement, ses différentes syntaxes le tout illustré par des exemples clairs. L’article aborde aussi le débogue du binding assez délicat puisque Xaml échappe au débogueur de Visual Studio, et que le binding n’est que partiellement couvert par Intellisense.

Des conseils, du vécu, beaucoup d’exemples, voilà ce que vous trouverez dans cet article à télécharger en suivant le lien suivant :

Le Binding Xaml – Maîtriser sa syntaxe et éviter ses pièges (WPF/Silverlight)

(Attention, avant de cliquer sur le bouton “télécharger” attendez que la fiche détail de l’article soit bien affichée, sinon le site pensera que vous tentez un accès à une ressource non publique et vous demandera un login… Je reçois tous les jours des demandes d’ouverture de compte provenant de lecteurs trop impatients qui cliquent trop vite sur le bouton ! La prochaine version du site en Silverlight est en préparation et corrigera ce petit problème, mais d’ici là : slow down cowboy !).

Pour vous aider à vous faire une idée du contenu de l’article voici son sommaire :

Sommaire

  • Références    5
  • Code Source    6
  • Préambule    7
  • Le Binding Xaml : Ange ou Démon ?    7
    • Le Binding    8
    • Définition    8
    • Utilisations    9
    • Schéma du principe    9
    • Déclaration    10
      • Par code    10
      • En Xaml    11
  • Les modes de binding    13
    • Le mode OneTime    13
    • Le mode OneWay    13
    • Le mode TwoWay    14
      • Gestion du timing    14
    • Le mode Default    16
    • Le mode OneWayToSource    16
  • Hiérarchie de valeur    18
    • Règles de précédences    19
  • La notion de  DataContext    20
  • Les convertisseurs de valeur    21
    • Définition    21
    • Scénario    21
    • Implémentation    22
    • Utilisation    23
      • Instanciation    23
      • Invocation    23
      • Bonnes pratiques    24
      • Pour résumer    26
  • Les dangers du Binding    27
    • Des chaînes non contrôlées    27
    • Un langage dans le langage    28
  • On fait quoi ?    28
  • Déboguer le Binding    28
    • Vigilance    28
    • Une code Xaml court    29
    • Refactoring sous contrôle    29
    • Utiliser des outils intelligents    29
    • Utiliser Expression Blend    29
    • Vérifier les erreurs de binding dans la fenêtre de sortie    30
    • Créer un fichier des erreurs de Binding    30
    • La feinte du convertisseur inutile    32
    • Quelques outils supplémentaires    33
      • Spy++    33
      • ManagedSpy    33
      • Snoop    34
      • Mole    34
      • Reflector    34
      • Vos neurones    34
  • Les syntaxes du Binding    34
    • Le binding simple    34
      • Binding direct    35
      • Binding sur une propriété    35
      • Binding sur une sous-propriété du contexte    36
      • L’Element Binding    37
      • Convertisseurs de valeur    37
        • Paramètres de conversion    38
      • StringFormat    40
        • Injection de culture    41
        • Le ContentStringFormat    42
        • Gérer les nuls    43
    • Le Binding Multiple    44
      • La classe Personne    44
      • Le code du multi convertisseur    45
      • Le code Xaml    46
    • Le Binding XML    47
      • Binding sur une source Web    47
      • Binding sur une source XML en ressource    48
      • Binding sur une requête Linq To XML    49
    • Le Binding Relatif    52
      • Binding to Self    52
      • Le TemplatedParent Binding    53
      • Le Binding sur recherche d’ancêtre    54
      • Le Binding PreviousData    56
        • La source de données    58
        • La visibilité des flèches : la magie de PreviousData et du Binding Multiple    58
        • Le contenu des textes    61
      • Le Template binding    61
        • Utilité    61
      • Le Collection Binding    67
      • Le Priority Binding    69
  • Les propriétés de tous les bindings    74
  • Conclusion    76

Avril est froid et pluvieux mais les soirées rallongent, c’est le printemps même si cela n’y ressemble pas encore beaucoup, grâce à moi vous savez maintenant comment occuper vos soirées et vos weekend au lieu de faire l’idiot dans les embouteillages des vacances : Lisez cet article !

Et Stay Tuned !

Le retour du spaghetti vengeur

Le code spaghetti est de retour ! Fuyez braves gens !

Sous-titré : Du Rififi dans le Xaml.

Avertissement au lecteur : ce billet, bien que bâti sur un fond technique préoccupant et une expérience réelle, utilise un formalisme un peu romancé. Ne cherchez pas d’extraits de code ici. Mais si vous avez un peu de temps, laissez vous porter par l’histoire. Si vous êtes pressés, revenez plus tard lire ce billet !

Genèse d’un malaise

Comme vous le savez je suis un passionné de WPF et de Silverlight, la puissance de Xaml servi par un Framework aussi riche que .NET et des outils de qualité comme Blend ou Visual Studio ne peuvent laisser de marbre (comment peut-il y avoir encore des gens travaillant sous Java ou Delphi ?). J’en suis tellement passionné que j’évangélise à tour de bras, ici et ailleurs, et que mes compétences autant techniques que de gardien des brebis égarées me valent d’avoir l’honneur d’être Microsoft MVP, notamment en 2010 pour les technologies de développement d’applications clientes (Client Application Development, “CAD”" MVP).

Bref, si je dis tout cela c’est pour faire comprendre que bien que cultivant mon objectivité comme un joyau précieux garant de la liberté de mes neurones, je suis plutôt “pro” Microsoft et que, bien entendu, cela peut déplaire à certains comme en séduire d’autres… La diversité du monde en fait sa richesse, isn’t it.

Et un partisan de Microsoft, MVP de surcroît, fan de Silverlight, ne dira jamais le moindre mal de sa technologie fétiche… Et soyez-en convaincu je ne briserai pas cette loyauté, essentielle à mes yeux, mais il faut pourtant savoir tirer les sonnettes d’alarme de temps en temps. D’ailleurs c’est une question de crédibilité, que vaudrait un expert sans liberté de parole ni de pensée… Et puis au fond vous verrez que c’est bien plus, comme à chaque fois, l’humain qui en prend pour son grade dans ce récit que les outils, innocents, par nature.

Tout cela pour parler franchement d’un risque, d’une dérive, et surtout d’un grand danger : le retour du code spaghetti ! Et, comble de l’infamie, la peur de cette tare qu’on croyait du passé, je ne la brandis pas à propos de langages ésotériques comme F#, ou de solutions vieillissantes comme Java. Non. Le drame est bien là : c’est de WPF et de Silverlight dont je veux vous entretenir, et ce, au travers d’une anecdote récente.

J’ai fait il y a quelques temps un audit dont je tairais, vous le comprendrez aisément, le nom du client visité ainsi que la date exacte. Au demeurant une société ni trop jeune pour n’être pas assez structurée, ni trop vieille pour en être devenue ringarde. Une entreprise de bonne taille, assez dynamique et assez typique de ma clientèle, se targuant de posséder une équipe de développement à la pointe du progrès, la preuve, puisque maniant les balises Xaml avec la même dextérité que la truelle l’est par un vrai maçon diplômé.

Le trait n’est pas forcé, il n’y en a nul besoin. Ce fut au début un audit “classique” c’est à dire durant lequel j’ai vu du code “normal” donc assez médiocre. Je dis “normal” au sens de la loi normale statistique ce qui signifie que grâce à  messieurs Laplace et Gauss il m’arrive de voir des choses épouvantables comme de pures merveilles, mais que ces deux cas représentent un pourcentage faible au deux bouts de la cloche… Je ne savais pas encore que j’allais atteindre le bout de la cloche. Le mauvais. Bien entendu.

Espèce de spaghetti !

Le code “normal” est médiocre généralement. C’est finalement une définition en soi. Le code exceptionnel, étant, par le même genre de raisonnement, plus rare. C’est finalement une lapalissade. Donc, en général, je vois du code médiocre, donc normal (dans l’autre sens c’est intéressant aussi, non ?).

Et j’appelle médiocre un code qui se caractérise par plusieurs aspects distinctifs très techniques que je détaille avec moult délicatesse dans mes rapports d’audit pour expliquer les choses en y mettant les formes mais qui se résument en général à quelques cas généraux qu’on pourrait caractériser très doctement. Je m’exprimerais ici de façon bien plus directe puisqu’on est “entre nous” :

  •  
    • La “putain” c’est à dire le code sur lequel tout le monde est passé, sauf le train et vous, mais ça, c’est même pas sûr, puisque vous êtes là… C’est du code typique des boîtes où les gens sont mal payé et où les salariés défilent plus vite qu’une hirondelle dans un ciel de printemps…
    • Les migrations de migrations de portage d’intégration (de milles sabords, version 24 bis modifiée E). En général du code qu’on trouve dans les administrations. Avec des documentations de plusieurs centaines de pages, que personne n’a jamais lu bien entendu.
    • Le code mille-feuille. Savoureuse pâtisserie constituée de tant de couches qu’on ne peut les compter, comme les pattes du iule (autrement appelé mille-pattes). C’est un peu un mélange des deux précédents mais en plus structuré que le premier (beaucoup plus, et c’est la son problème) et en moins documenté que le second (beaucoup moins, et c’est aussi là son problème). C’est du code de SSII “in” avec de vrais morceaux de “nouvelles technos” dedans.
    • Le code “start-up”, celui-là est bourré de technos innovantes, hélas non maîtrisées, peu documentées et en bêta ne tournant que sur les versions US de l’environnement. Un code d’essayiste pur travaillant pour la beauté du discours qui va autour plus que pour l’efficacité, des gens qui devraient être en agence de pub plutôt que devant un environnement de développement.
    • Le code à papa, ou l’objet est utilisé comme du C procédural. C’est le code C# écrit par de vieux delphistes ou cobolistes reconvertis sur le tard par exemple.
    • Le code d’ingénieur, un des pires. Sortant de l’école et voulant montrer ses muscles en complexifiant tout et l’enrobant dans une prose technique pleine de sigles bizarres et de référence à des bouquins lus de lui seul et de ses potes de promo. Quand il arrêtera de sucer son pouce, il deviendra un bon développeur sévèrement burné comme disait Tapie. Mais en attendant son code c’est l’enfer…
    • Et enfin, le célèbre, le magnifique, le code spaghetti, marquant l’incompétence à maîtriser la complexité du sujet. Celui-là est typique des mauvaises équipes, tous contextes confondus.

Il y en a bien d’autres dans mon bestiaire, en 20 ans d’audit vous imaginez ce que j’ai pu voir (heureusement je rencontre aussi des équipes compétences et même parfois de l’excellent code, sinon ça serait désespérant !).

Et WPF et Silverlight dans tout ça ?

C’est là que je voulais en venir, mais il fallait bien passer par ce détour pour vous plonger dans l’ambiance trouble de cette descente aux enfers binaires. Sinon cela aurait été d’une platitude redoutable. Un peu de lecture ça change des extraits de code en Xaml. Justement. Parlons de lui et de ce dernier audit (qui n’est pas le dernier, confidentialité oblige comme je le disais plus haut). Disons que c’est assez récent pour être en Xaml mais pas suffisamment pour être en Silverlight 3.

Qu’avait ce code qui vaille ce billet un peu particulier ?

Le code qui rend fou

il m’a rendu fou. Tout simplement ! Et en plus il m’a filé les chocottes !

WPF et Silverlight sont des technologies merveilleuses, Xaml a un pouvoir descriptif exceptionnel à tel point qu’il permet d’économiser beaucoup de code behind.

Malgré le génie des équipes MS ayant travaillé sur le Framework j’aurais malgré tout préféré que cette révolution se fasse à 100% dans le respect du paradigme objet et du fortement typé. Or ce ne fut pas totalement le cas, et si je comprends bien les contraintes techniques sous-jacentes qui ont interdit cet idéal, certains choix sont hélas autant de portes ouvertes sur des risques que je viens de palper de près. Et ça fait peur.

Il y a en premier lieu l’architecture. Il ne suffit pas de prendre Prism et ses Dll pour avoir un bon logiciel. Il faut comprendre et maîtriser la chose. Ce qui ne s’improvise pas. Mais il y a pire, car plus lié à la technologie elle-même.

Par exemple, prenez la syntaxe du Binding, en Xaml donc. Vous avez une balise, vous la complétez d’une propriété et là, au lieu de mettre une valeur, vous ouvrez des accolades américaines suivies du mot Binding, le tout entre guillemets, une simple chaine de caractères. Quant à ce qu’il y a après le mot Binding, je suis convaincu qu’aucun aficionado de WPF ou de Silverlight n’est capable de me citer de tête toutes les combinaisons possibles et astuces disponibles. Parfois  c’est {Binding} tout court, parfois c’est une longue phrase intégrant imbriquées d’autres accolades faisant référence à des ressources statiques ou dynamiques, des paramètres, des convertisseurs, etc… Une puissance énorme, un peu comme les expressions régulières : puissant mais pas très clair (et c’est un euphémisme). Pas clair, on peut s’y faire… mais pas clair et pas fortement typé ni même contrôlé, c’est là que la chute aux enfers commence…

Le code que j’ai audité était bourré d’element binding, de datacontext pointant des conteneurs de services avec des indirections dans tous les sens “pour la souplesse”. Quand MVC et MVVM ne sont pas compris, mieux vaut tout mettre en procédural dans le code-behind de chaque fiche, c’est plus simple à débugger ! Le pire c’est que chacun dans l’équipe y allait de sa petite couche, de sa petite modification. Et je fais du “refactoring” par là, et je refactore par ici… Oui mais voilà, dans les balises Xaml ça commence à danser le cha-cha-cha toutes ses chaînes de caractères non contrôlées, tous ces paramètres de convertisseurs qui ont évolués sans qu’on ait mis à jour les références dans le Xaml, ces ressources statiques et d’autre dynamiques dans des dictionnaires chargés dynamiquement !

Le soft ne tenait plus que par un fil qu’un joyeux drille a du couper juste avant que je n’intervienne. Dommage. Je n’arrivais même pas à dépasser un ou deux écrans avant que ça me pète à la figure. Même avec des outils très intelligents comme NDepend, comprendre le soft était virtuellement impossible.

Quant à savoir d’où vient “le” problème ! C’est le soft lui-même tout entier qui était “le” problème… Ainsi que ceux l’avaient écrit (et ceux qui les dirigent, car un mauvais soft est toujours la cause d’une mauvaise direction bien plus que de mauvais développeurs).

En fait, le Binding Xaml est une porte ouverte sur l’inconnu. Une feature d’une grande puissance, sans laquelle beaucoup du charme disparaîtrait, mais assez déraisonnable dans cette implémentation libre sous forme de chaînes de caractères non compilées. La porte sur le néant, l’incontrôlé, et pire : l’incontrôlable. Un trou noir syntaxique. La damnation du testeur envoyé moisir au purgatoire des pisseurs de ligne. Et l’enfer de l’auditeur.

le Binding au pays des X-Files

Le Data binding Xaml est une jungle syntaxique pas très bien … balisée et totalement déconnectée de toute forme d’analyse à la compilation. du “Late Bugging” comme je m’amuse à appeler cette stratégie de type “late binding”, principe de ligature tardive utilisé d’ailleurs en d’autres endroits et même sous d’autres frameworks. Pire que les Dynamic de C# 4 (pratiques mais dangereux), pire que F# (stimulant mais pas industrialisable), le Binding de Xaml est un gouffre à bugs, un chien fou s’il n’est pas tenu en laisse fermement.

En réalité un marteau ne pourra jamais être jeté aux fers (!) pour le meurtre de qui que ce soit. Un marteau est un outil, et même s’il a servi et servira encore dans de nombreux crimes, un outil est un objet sans âme, sans conscience et donc sans responsabilité. Même un fusil mitrailleur est un objet innocent, même un canon de 105 ou une bombe atomique sont plus innocents que l’agneau qui vient de naître et qui, comme tout être vivant, et à la mesure de son intelligence, portera le poids de la responsabilité de ses agissements. Un outil de développement restera donc à jamais hermétique à tout procès d’intention. A celui qui s’en sert de le faire correctement.

Il en va de même de Xaml, de son data Binding et de bien d’autres de ces facettes. La responsabilité incombera toujours à l’humain qui tient le marteau. A l’informaticien qui tient la souris. Au développeur qui tape un code affreux.

Mais certaines features de Xaml, certains choix conceptuels comme l’utilisation de chaînes de caractères non contrôlées et non parsées à la compilation sont à mon sens des erreurs. Si des projets comme celui que j’ai audité et dont je vous parle ici devenaient courants, nul doute que cela signerait l’arrêt de mort de WPF et de Silverlight. La faute aux mauvais développeurs ? Pas seulement. A ceux aussi qui ont décidé de programmer Xaml de cette façon trop ouverte, trop permissive. On voit bien comment Silverlight a été verrouillé dès le départ par Microsoft. Si le moindre virus, le moindre phishing avait été réalisé avec Silverlight 1 ou 2 c’en était fini des espoirs portés par cette technologie. Microsoft a été méfiant pour préserver l’avenir de la technologie et c’est une bonne chose. Ce que j’ai vu dans le projet WPF dont je parle ici, c’est un peu de la même nature, mais à l’inverse : Microsoft n’a pas verrouillé Xaml comme cela a été fait avec Silverlight. Et si de tels détournements se généralisent c’est toute la technologie qui trinquera. D’ici un an environ, lorsque les projets lancés ces derniers temps seront finalisés, et qu’il faudra compter ceux qui n’aboutiront pas ou qui ne marcheront jamais bien, la note peut être salée pour Xaml. Microsoft a pris un sacré risque en faisant des choix de conception comme celui des balises non compilées (et dans lesquelles même Intellisence se prend les pieds dans le tapis).

Déjà sous Delphi je voyais souvent ce genre de code spaghetti avec des variables globales référencées n’importe où, des fiches utilisant des variables d’autres fiches jusqu’à créer des chaines de dépendances ingérables. J’ai vu des codes de ce type ne pouvoir jamais aboutir. Il m’est même arrivé une fois de réécrire en 15 jours proprement à partir de zéro un soft développés en 1 an par deux personnes sans le dire au client histoire que les 15 jours d’expertise qu’il m’avait payés servent à quelque chose… Je tairais ici le nom du client (une administration). J’étais plus jeune et je voulais me prouver des choses certainement, mais personne ne l’a jamais su jusqu’à ce billet (et encore vous en savez peu!). En tout cas ce projet là je l’ai sauvé. Mais être un pompier de l’ombre n’est pas ma vocation. Les gars étaient malgré tout étonnés ne pas vraiment s’y retrouver dans “leur” code. Amusante situation. Je n’avais rien gardé de “leur” code :-) Mais le soft marchait…

Mais avec Xaml, et une puissance décuplée, je viens de voir des horreurs du même genre alors que depuis des années, je commençais à trouver que C# incitait plutôt à faire du code “correct”, le niveau étant globalement meilleur que celui que je voyais sur Delphi. Et patatras ! Xaml arrive avec ces chausses-trappes dans lesquels les développeurs s’engouffrent. La faute à Xaml ? Pas totalement, mais si tout était typé et contrôlé à la compilation certaines mauvaises utilisations ne seraient pas possibles. Après tout, le fortement typé en soi ça ne sert à rien si on suppose que tous les développeurs sont “bons” ! Mais tous les langages modernes tentent de l’être car on sait que l’humain est faillible. En créant une brèche incontrôlable dans un édifice aussi beau de Xaml, ses concepteurs ont fait un pari risqué. Celui que tous les développeurs sauraient maîtriser le potentiel sans tomber dans ses pièges. Un pari forcément perdu d’avance.

Vision d’horreur

Ce que j’ai vu est donc indescriptible. Un peu comme si j’essayais de décrire Cthulhu. Ceux qui ont essayés sont souvent morts avant de finir d’écrire son nom (ah Lovecraft…) !

Imaginez vous un logiciel de 250 fiches WPF environ utilisant de l’ADO.NET, des bouts de LINQ to SQL, et des nouveautés en Entity Framework, le tout à la sauce Prism / MVC (mais en ayant lu le manuel certainement à l’envers car Prism c’est très bien !) avec des tentatives d’inversion de contrôle (et des dérapages non contrôlés) farci d’un code Xaml bourré de Binding renvoyant vers on ne sait quoi (et hélas pas contrôlé à la compilation), le tout planqué dans 4 ou 5 couches DAL, BOL pré-BOL, post-BOL, et j’en passe, histoire de faire court. La note s’élève a 6000 jours/homme (5 ans/homme environ). Pas un truc gigantesque mais qui commence à faire mal au budget malgré tout.

Agrémentez le tout de deux systèmes de versionning dont aucun n’avait vraiment une version complète du soft, des essais épars de tests unitaires avec MbUnit et VSTS. Vous obtiendrez le tableau. Une œuvre qui dépasse le classicisme habituel de ce point de vue, plus proche du Cubisme que de l’Hyperréalisme tout de même, avec au moins la bonne volonté de faire des petites choses (du mauvais testing prouve au moins qu’on a essayé de tester, ce qui est encore bien rare…). Mais l’enfer est pavé de bonnes intentions, c’est un peu ça le problème.

Le code était impossible à maintenir, les problèmes de performances impossible à cerner sans y passer plus de temps qu’à toute refaire, le code Spaghetti, avec un grand S avait frappé de son coup de poignard vengeur et lâche dans le dos. Une complexité non maîtrisée qui tel l’horizon d’un trou noir aspirait irrémédiablement le bon code vers l’enfer central laissant le hasard faire le tri entre les chemins à prendre… Démêler l’écheveau n’était pas possible, pas plus que de formuler des guidelines sérieusement applicables dans un tel contexte ni aucun conseil pour se sortir d’une telle situation.

Vous imaginez peut-être l’horreur qu’a été l’écriture du rapport d’audit. Entre dire une vérité que personne n’était prêt à entendre et mentir sachant que peu importe ce que je dirais cela passerait mal et qu’au fond mieux valait ne pas trop déplaire… Mon éthique a tranché, j’ai dit la vérité. En l’enrobant. Des heures passées à réécrire deux fois, dix fois certains paragraphes. Ils ne s’en douteront jamais… Et au final un rapport qui sera peut-être classé au fond d’un tiroir car personne ne voulait vraiment savoir ce qui n’allait pas. La remise en question d’un tel échec dépasse de loin le cadre technique et peu de gens savent admettre leurs erreurs, surtout quand toute la chaîne hiérarchique de la base au sommet doit participer à ce questionnement.

Le salaire de la peur

La peur dont je parlais plus haut, les chocottes que cet audit m’a données, c’est d’être confronté au fleuron de la technologie informatique, à des choses en lesquelles je crois car elles marquent un réel progrès et que (bien utilisées) elles permettent justement un code limpide. Cet audit a brisé ce fantasme en me rappelant qu’un marteau pouvait servir au meilleur, comme au crime. Xaml, WPF et Silverlight n’échapperaient pas à la règle et il faudra être vigilant. Surtout que l’avalanche de technologies et de patterns (WCF Ria Services, Entity Framework, MVVM, Prism, …) rendent presque impossible la maîtrise de tous ces sujets. Je suis payé pour ça. Au minimum 50% de mon temps est passé en autoformation pour apporter un conseil éclairé sur les technos à venir. Ce sont les 50% vendus qui financent cette formation et cette recherche permanente. Comment un développeur qui fait ces 48h (35 de base + le dépassement obligatoire non payé car il est aux “cadres”) peut-il se former à tout cela en travaillant sur d’autres projets la journée ? C’est impossible. Et cela créé une situation très dangereuse. Technologie sophistiquée + manque de formation = code spaghetti !

David Vincent au pays des tags

Il était donc urgent de vous en parler, d’attirer votre attention sur certaines dérives, car dans une moindre mesure, je sais, je l’ai vu chez d’autres, ces chausses-trappes savent s’ouvrir sous les pieds des développeurs les mieux formés et les mieux intentionnés !  Je les ai vues, et je dois convaincre un monde incrédule…

Ma mission, que j’ai acceptée (forcément avant de voir, on a pas vu…), était de faire un audit de pré-release. C’est à dire de venir faire le point sur l’état de la situation, les derniers fameux “boulons à serrer” en quelque sorte, et surtout de venir signer un satisfecit au DI, très fier de son bébé (Rosemary’s baby plutôt que Dora de TF1 au final), afin qu’il puisse faire monter sa prime de fin d’année je suppose.

Hélas, déception et vilenie. Ce n’est pas avec le prix d’un audit (fort raisonnable, devis gratuit sur simple demande) qu’on achète ma conscience. Il m’a donc fallu trouver les mots et les formules diplomatiques pour rendre un audit policé et mesuré sur cet édifice in-maintenable, voué à l’échec et bon à mettre à la broyeuse. Ce n’est pas la partie la plus difficile, car tout rapport d’audit se doit d’être policé et tourné de façon neutre et technique. Même si parfois on a envie de crier “bande de nuls !”, non, ce n’est pas bien, on ne le fait pas…

Que les futurs clients ne s’affolent pas trop, ce que je raconte aujourd’hui est malgré tout à classer dans les exceptions, le fameux bout de la cloche de la courbe Normale. Même si je ne suis que rarement content du code que je vois, on est, heureusement en moyenne, assez loin de l’horreur qui justifie le présent billet !

O Tempora, O Mores !

Parfois je rêve, j’imagine un monde où l’un de ces clients m’appellerait en me proposant un pont d’or pour lui avoir ouvert les yeux et l’avoir empêché de plonger plus encore tant qu’il était encore temps… Mais ce n’est qu’un rêve, bien entendu. Je suppose que je n’entendrais plus parler de ce client comme de quelques autres dont, les années passant et les vœux annuels restant sans réponse m’ont forcé à une résignation réaliste. Comme le chantait l’artiste, “il a dit la vérité, il doit être exécuté” !

Hélas, les temps ne sont pas à la prise de conscience ni à la bravoure. Nous vivons une époque de lâches où chacun ouvre son parapluie pour que les gouttes en atteignent d’autres. Forcément celui qui est au plus bas de la pyramide se prend tout sur la figure. Souvent c’est le développeur qui trinque pour une chaîne hiérarchique défaillante qui n’a pas fait son métier et qui n’assume pas ses responsabilités. Un développeur n’est jamais coupable seul d’un mauvais code, c’est toute la chaine de commandement qui faillit.

Il y a encore un rêve que je fais et que j’aimerais voir se réaliser avant ma (encore lointaine) retraite : que les entreprises fassent intervenir un conseil, un auditeur avant que l’irréparable ne soit commis, pas après pour constater les dégâts ! … ça serait tellement mieux et plus gratifiant pour moi et mes confrères ! Conseiller, orienter, former, en un mot aider, c’est tout de même plus chouette que de passer pour le père fouettard et l’inspecteur des travaux finis !

Faut-il brûler Xaml ?

Certes non.

Mais ce que je veux qu’il vous reste de ce récit hallucinant autant que réel, c’est que Xaml est utilisé par certains comme un langage dans le langage. Un moyen de vider le code-behind de son C# pour remplir des balises ésotériques. Un langage dans le langage avec son Binding qui est, telles le sont les poupée Russes, encore un langage dans le langage.

A vouloir tout faire par binding, à tout dynamiser, à appliquer tout Prism et le chargement dynamique des modules, la découvertes des plugins avec MEF, le tout mis en forme façon MVVM, sans compter les ruses purement graphiques du templating sous Blend, des DataTemplate à double face pivotante en 2,5 D, à vouloir appliquer tout cela dans un seul soft sans avoir pris les 2 ou 3 ans nécessaires à acquérir la parfaite maîtrise méthodologique pour faire marcher tout cela ensemble, on peut facilement arriver à une situation désastreuse. Encore plus facilement que sous C, encore plus que sous Delphi, pire que sous Windows Forms. Tout cela n’était que de l’amateurisme face aux dérapages délirants que WPF et Silverlight peuvent permettre… Comment faire des tests unitaires parlants sur des balises de Binding imbriquées à un tel point que même Intellisense de VS s’y perd ?

L’extrémisme essayiste est un fléau dans notre métier. Il m’a toujours effrayé, mais il a toujours eu sa sanction “naturelle” : une technologie qui finit par être si mal utilisée créée une telle publicité négative qu’elle tend à disparaître. Je ne voudrais pas que cela arrive à WPF et à Silverlight qui apportent tant d’autres progrès !

Il faut sauver le soldat Xaml !

Pitié pour Xaml, un bon geste pour WPF et Silverlight : ne laissez pas des sagouins faire du mal à toutes ces belles technologies que Microsoft nous offre depuis quelques années. Laissez leur une chance, celle que les développeurs deviennent plus matures et mieux formés aux méthodologies qui vont avec. Ne commettez pas le crime d’être complice de ce genre de chose. Intégrer les technologies les unes après les autres, ne sautez pas d’une bêta à l’autre sans avoir l’assurance que vous maîtrisez la précédente !

Mieux vaut une application Silverlight fonctionnant avec un Service Web classique et dont les champs sont connectés par code, qui marche et qui est maintenable, qu’une élucubration technologique improbable et non maîtrisée qui s’écroulera comme un château de carte au premier éternuement du premier bug venu…

Un peu de sérieux…

Il ne s’agit pas d’une invitation à la méfiance, encore moins au passéisme. Non, c’est une invitation au professionnalisme : n’utilisez que ce que vous maîtrisez.

Si vous maîtriser le top de la techno, allez-ci, franchement. Si vous avez un petit doute : faites joujou dans une machine virtuelle et produisez du code que vous comprendrez à 100% et surtout que d’autres pourront comprendre pour le maintenir, le faire vivre dans les années à venir.

Le code Kleenex coûte cher, il dévalorise notre métier et les outils que nous utilisons.

Le code spaghetti peut assassiner une technologie.

Codez bien. Formez-vous bien.

Et faites auditer vos projets avant, pas après.

Et Stay Tuned, j’aurais des trucs plus légers à vous dire la prochaine fois !

Fichiers PFX de signature de projet Visual Studio / objet déjà existant après migration Windows 7

Vous l'avez compris, l'entrée de blog d'aujourd'hui ne parle pas de Silverlight ni d'autres sujets technologiques passionnants mais d'un problème très ennuyeux intervenant après la migration sous Windows 7. Cela concerne les projets signés numériquement sous Visual Studio, ceux possédant un fichier PFX donc.

Une fois cette migration effectuée, tout semble tellement bien marcher que vous lancer fièrement Visual Studio sans vous douter du complot sournois qui se trame contre vous et qui se révèlera au moment où vous tenterez d'ouvrir une solution contenant des projets signés... Vous allez me dire, l'attente est courte. En effet, il est rare d'ouvrir VS juste pour le plaisir de le regarder, assez rapidement, même pour les plus lents d'entre nous, on finit par faire Fichier / Ouvrir (les plus créatifs préférant Fichier / Nouveau, mais ce n'est pas le sujet du jour).

A ce moment là, tous les projets signés déclenchent une importation du fichier PFX (même si vous êtes toujours sur la même machine et que rien n'a changé, n'oubliez pas que cette machine vient de migrer de Vista à 7 !). Comme vous êtes un développeur honnête, vous connaissez bien entendu les mots de passe des fichiers PFX de vos projets. Donc pas de problème vous tapez le mot de passe. Bang ! Erreur "l'objet existe déjà" (Object already exists). Et pour peu que votre solution contienne des dizaines de projets, ce qui est mon cas assez fréquemment, vous allez boucler sur cette séquence pour tous les fichiers PFX. A la fin vous pourrez travailler sur votre solution, mais à toute tentative de compilation vous vous reprendrez la même séquence : importation de la clé, demande de mot de passe, échec pour cause d'objet existant, etc pour chaque projet signé.

C'est un peu gênant... Mais il existe une raison et une solution !

La raison, en tout cas pour ce que j'en ai vu, c'est que la migration vers W7 modifie les droits du répertoire dans lequel sont cachés les clés importées. Pourquoi ? Je n'en sais rien et pour l'instant je n'ai rien trouvé sur le Web à ce sujet.

En tout cas, le problème étant identifié, il existe une solution : changer les droits et s'approprier le dit répertoire. Ca peut être plus compliqué que prévu, en tout cas j'ai galéré un peu (j'avoue franchement ne pas avoir un niveau d'expert en matière de gestion de sécurité sous Windows). En effet il faut déjà trouver le répertoire en question. (roulements de tambours) c'est... c'est... C:\Users\All Users\Microsoft\Crypto\RSA

Maintenant que faire... Clic droit sur le répertoire (dont l'image possède un petit verrou d'ailleurs, verrou qui disparaitra en fin de manip), onglet sécurité et on essaye de s'approprier tout ça. Ca plantouille car Windows répond qu'on n'a pas les droits sur xxxx (à remplacer par le nom imbuvable de chaque fichier de ce répertoire, justement ceux posant problème).

Bref, il faut y aller à la main. On entre dans le répetoire et on fait un clic droit / sécurité sur chaque fichier. Certains laissent voir la page Sécurité immédiatement. Laissez tomber. Mais un certain nombre d'autres fichiers affichent un message vous indiquant que vous n'avez pas le droit de voir l'onglet Sécurité ! Heureusement Windows vous permet de vous les approprier, donc d'en devenir le propriétaire (au passage je vois mal l'intérêt d'interdire un truc en proposant de l'autoriser, je vous l'ai dit, je ne suis pas un expert en Sécurité Windows !). C'est ce que j'ai fait pour chaque fichier. En fin de manip j'ai recommencé la modification des droits sur le répertoire lui-même, et là c'est passé. Plus de petit verrou affiché dans le symbole dossier.

Et immédiatement, Visual Studio ne redemande plus l'importation des clés. Ca remarche. Ouf !

Je suis convaincu que je m'y suis pris comme un pied pour régler le problème (il doit y avoir plus simple et plus propre que de devenir propriétaire de chaque fichier un par un), en tout cas ça règle bien le problème qui avait été bien identifié : problème de droits sur le répertoire des clés.

Pour l'instant c'est la seule surprise que j'ai eu en migrant cette machine de Vista à Windows 7. Le reste marche très bien et on ne perd rien ce qui est très appréciable (comme j'aurai aimé que cette option de migration sans douleur existe sur les anciennes versions de Windows !).

J'espère que le récit de cette mésaventure (et surtout sa solution) évitera à certains de perdre quelques heures... Si oui, n'hésitez pas à me le dire, ça fait toujours plaisir de savoir qu'un billet a été utile !

Et sir parmi vous il y en a qui sont plus doués que moi niveau sécurité Windows, qu'ils n'hésitent pas à indiquer la "bonne" manip pour arriver au résultat je modifierai en conséquence le présent billet...

Dans tous les cas, Stay Tuned !

C# - Les optimisations du compilateur dans le cas du tail-calling

Les optimisations du compilateurs C# ne sont pas un sujet de discussion très courant, en tout cas on voit très nettement que le fait d'avoir quitté l'environnement Win32 pour l'environnement managé de .NET a fait changer certaines obsessions des codeurs... Ce n'est pas pour autant que le sujet a moins d'intérêt ! Nous allons voir cela au travers d'une optimisation particulière appelée "tail-calling" (appel de queue, mais je n'ai pas trouvé de traduction française, si quelqu'un la connaît, qu'il laisse un commentaire au billet).

Principe

On appelle "tail-calling" un mécanisme d'optimisation du compilateur qui permet d'économiser les instructions exécutées en même temps que des accès à la pile. Les circonstances dans lesquelles le compilateur peut utiliser cette optimisation sont celles où une méthode se termine par l'appel d'une autre, d'où le nom de tail-calling (appel de queue).

Prenons l'exemple suivant :

static public void Main()
{
    Go();
}
 
static public void Go()
{
    Première();
    Seconde();
    Troisième();
}
 
static public void Troisième()
{
}

Dans cet exemple le compilateur peut transformer l'appel de Troisième() en un appel de queue (tail-calling). Pour mieux comprendre regardons l'état de la pile au moment de l'exécution de Seconde()  : Seconde()-Go()-Main()

Quand Troisième() est exécutée il devient possible, au lieu d'allouer un nouvel emplacement sur la pile pour cette méthode, de simplement remplacer l'entrée de Go() par Troisième(). La pile ressemble alors à Troisième()-Main().

Quand Troisième() se terminera elle passera l'exécution à Main() au lieu de transférer le trait à Seconde() qui immédiatement devra le transférer à Main().

C'est une optimisation assez simple qui, cumulée tout au long d'une application, et ajoutée aux autres optimisations, permet de rendre le code exécutable plus efficace.

Quand l'optimisation est-elle effectuée ?

La question est alors de savoir quand le compilateur décide d'appliquer l'optimisation de tail-calling. Mais dans un premier temps il faut se demander de quel compilateur nous parlons.... Il y existe en effet deux compilateurs dans .NET, le premier prend le code source pour le compiler en IL alors que le second, le JIT, utilisera ce code IL pour créer le code natif. La compilation en IL peut éventuellement placer certains indices qui permettront de mieux repérer les cas où le tail-calling est applicable mais c'est bien entendu dans le JIT que cette optimisation s'effectue.

Il existe de nombreuses règles permettant au JIT de décider s'il peut ou non effectuer l'optimisation. Voici un exemple de règles qui font qu'il n'est pas possible d'utiliser le tail-calling (par force cette liste peut varier d'une implémentation à l'autre du JIT) :

  • L'appelant ne retourne pas directement après l'appel;
  • Il y a une incompatibilité des arguments passés sur la pile entre l'appelant et l'appelé ce qui imposerait une modification des arguments pour appliquer le tail-calling;
  • L'appelant et l'appelé n'ont pas le même type de retour (données de type différents, void);
  • L'appel est est transformé en inline, l'inlining étant plus efficace que le tail-calling et ouvrant la voie à d'autres optimisations;
  • La sécurité interdit ponctuellement d'utiliser l'optimisation;
  • Le compilateur, le profiler, la configuration ont coupé les optimisations du JIT.

Pour voir la liste complète des règles, jetez un oeil à ce post.

Intérêt de connaitre cette optimisation ?

Normalement les optimisations du JIT ne sont pas un sujet intéressant au premier chef le développeur. D'abord parce qu'un environnement managé comme .NET fait qu'à la limite ce sont les optimisations du code IL qui regarde directement le développeur et beaucoup moins la compilation native qui peut varier d'une plateforme à l'autre pour une même application. Ensuite il n'est pas forcément judicieux de se reposer sur les optimisations du JIT puisque, justement, ce dernier peut être différent sans que l'application ne le sache.

Qui s'intéresse à l'optimisation du tail-calling alors ? Si vous écrivez un profiler c'est une information intéressante, mais on n'écrit pas un tel outil tous les jours... Mais l'information est intéressante lorsque vous déboguez une application car vous pouvez vous trouver face à une pile d'appel qui vous semble "bizarre" ou "défaillante" car il lui manque l'une des méthodes appelées !

Et c'est là que savoir qu'il ne faut pas chercher dans cette direction pour trouver le bug peut vous faire gagner beaucoup de temps... Savoir reconnaître l'optimisation de tail-calling évite ainsi de s'arracher les cheveux dans une session de debug un peu compliquée si on tombe en plus sur un pile d'appel optimisée. Un bon debug consiste à ne pas chercher là où ça ne sert à rien (ou à chercher là où c'est utile, mais c'est parfois plus difficile à déterminer !), alors rappelez-vous du tail-calling !

Et stay tuned !

nota: le présent billet est basé sur un post de l'excellent blog ASP.NET Debugging

Debug ou Cracking ? Des outils .NET à la frange des deux mondes...

Un debugger comme celui de Visual Studio n'est que rarement comparé à un outil de cracking pour la bonne raison que son utilisation s'effectue systématiquement (ou presque) sur des applications en cours de développement / maintenance, impliquant que l'opérateur du debug a le droit d'accéder aux sources. Mais comment catégoriser les outils qui suivent ?

Les trois outils dont je vais vous parler aujourd'hui se situent tous à la limite entre debugging et cracking, non pas forcément par la volonté de leur concepteur mais bien par leur nature. Il s'agit en fait d'applications autonomes capable de percer les secrets d'applications .NET en cours de fonctionnement (2 outils sur les 3 pour être précis, l'un est un visualisateur pour VS).

Outils de debug très intéressants ne nécessitant pas forcément l'installation de VS sur la machine, ces applications sont des compagnons à mettre dans votre boîte à outils. Utilitaires autonomes pouvant être utilisés par n'importe qui, l'existence même de ces outils ouvre la voie à un cracking autrement plus simple que l'utilisation d'outils comparables pour Win32. La haute cohérence de .NET et sa "lisibilité" rendant l'opération moins ardue.

Anges ou Démons ?

Les objets n'ont pas d'âme (si tant est que les êtres vivants en aient une) mais surtout ils n'ont pas de conscience. De tels outils ne peuvent donc être taxés en eux-mêmes d'être "diaboliques". C'est l'Homme qui appuie sur la gâchette que l'on juge et condamne, non les particules de poudre et l'amorce ayant permis à la balle de sortir de l'arme... A vous d'en faire bonne usage donc. Le plus important étant même de savoir que de tels outils existent pour éventuellement réfléchir, pour des applications sensibles, à comment rendre inopérantes des attaques qui utiliseraient cette approche.

Les outils

Crack.NET

Ecrit par Josh Smith, cet outil est un "logiciel de débogage et de scripting qui vous donne accès à l'intérieur de toute application .NET desktop" (d'après la traduction de la présentation de l'auteur). Une fois lancé l'utilitaire permet de choisir l'application .NET à cracker (selon les termes mêmes du bouton de lancement). Visualiser la mémoire, traverser les grappes d'objets, il est ainsi possible de tracer l'état de l'application "victime". Imaginons un mot de passe de connexion à une base de données ou à un Service Web, même si l'exécutable est obfusqué, même si les valeurs sont cryptées sur disque, il devient possible de lire ces dernières en clair une fois en mémoire de l'application.

On flirte avec la limite cracking / debugging, mais encore une fois l'intention coupable ou non est du ressort de la conscience de l'utilisateur de l'outil.

Un outil à posséder donc.

http://joshsmithonwpf.wordpress.com/cracknet/

Mole

Mole est un outil un peu différent, c'est un visualisateur pour Visual Studio qui permet de plonger dans les arborescences d'objets, de visualiser les valeurs mais aussi de les modifier.

En tant qu'outil pour VS la frontière du cracking s'éloigne, celle du debugging étant plus clairement visible.

"Mole a été conçu pour permettre au développeur non seulement d'afficher des objets ou des données, mais aussi de percer et visualiser les propriétés de ces objets, puis de les modifier. Mole permet un nombre illimité d'objets et de sous-objets en cours d'inspection. Quand Mole trouve un objet IEnumerable, les données peuvent être visualisées dans une DataGridView ou dans une grille de propriétés. Mole gère facilement les collections qui contiennent plusieurs types de données. Mole permet aussi au développeur de voir les champs non publics de tous les objets. Vous pouvez apprendre beaucoup sur le framework. NET en inspectant ainsi les données de vos applications."

http://karlshifflett.wordpress.com/mole-for-visual-studio/

Snoop

"Snoop est un utilitaire conçu pour simplifier le débogage visuel des applications WPF à l'exécution."

Un peu comme Crack.NET il s'agit ici d'un utilitaire autonome permettant d'inspecter une application WPF lors de son exécution. Cela peut s'avérer très utile en debug, mais peu présenter certains risques entre de mauvaises mains...

 

En tout cas, si vous développez des applications WPF, il faut avoir Snoop, il peut fournir une aide appréciable en plus du debug sous VS.

http://blois.us/Snoop/

Conclusion

Objets inanimés avez-vous une âme ? Questionnait Lamartine. Les objets numériques qu'il n'a pas connus n'en ont ni plus ni moins que les objets physiques en tout cas. Cracker ou debugger, c'est à vous de voir avec votre conscience, mais dans tous les cas, il est important de connaître l'existence de tels outils qui peuvent s'avérer bien pratiques dans certaines circonstances.

Stay Tuned !

Améliorer le debug sous VS avec les proxy de classes

Visual Studio est certainelement l'IDE le plus complet qu'on puisse rêver et au-delà de tout ce qu'il offre "out of the box" il est possible de lui ajouter de nombreux add-ins (gratuits ou payants) permettant de l'adapter encore plus à ses propres besoins. Ainsi vous connaissez certainement les "gros" add-ins comme Resharper dont j'ai parlé ici quelque fois ou GhostDoc qui écrit tout seul la doc des classes. Vous connaissez peut-être les add-ins de débogage permettant d'ajouter vos propres visualisateurs personnalisés pour le debug. Mais vous êtes certainement moins nombreux à connaître les proxy de classes pour le debug (Debugger Type Proxy).Plus...