Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Xamarin.Forms : les mystères de la messagerie embarquée !

Est-elle plus lente, moins efficace que les autres ? Mais surtout est-elle exploitable simplement alors même que sa documentation officielle est fausse ? Faisons le point !

Les messageries MVVM

Je ne suis pas un grand fan des messageries utilisées dans les toolkits MVVM. Une raison à cela que j’ai déjà exposée plusieurs fois : très vite on obtient du “message spaghetti” avec l’inconvénient majeure qu’à la différence du code qui peut être tracé facilement (avec les outils de VS ou Resharper par exemple), les messages sont invisibles, insaisissables et forment à la longue des sacs de nœuds.

Bon, cela étant dit les messageries sont tout de même très utiles notamment en ce qu’elles aident à appliquer un découplage fort au sein du code.

Je ne ferai pas de redites quant à leur utilité, leur histoire, et tout cela puisque j’ai consacré pas moins de deux vidéos Dot.Vlog à ce sujet !

Alors à quoi sert le billet d’aujourd’hui ?

Bien que traité dans les deux vidéos je me suis aperçu que l’utilisation même de la messagerie Xamarin.Forms continuait à poser problème. D’une part on ne visionne pas deux vidéos aussi facilement qu’on lit rapidement une entrée de blog, d’autre part ce problème n’était pas le sujet central de ces vidéos qui traitent des messageries MVVM en général.

Bug de Doc

Depuis longtemps, depuis le début certainement, la documentation Xamarin devenue Microsoft à propos de la messagerie est à côté de la plaque. Elle induit en erreur par des explications qui ne reflètent pas la réalité du code. Et pire, même ce dernier utilise une terminologie trompeuse pour certains paramètres… Signalé mais jamais corrigé ce bug dans la doc porte préjudice à cet outil malgré tout indispensable dans le cadre de MVVM.

On s’en fiche on utilise la messagerie du toolkit xxx !

C’est une façon de régler le problème en effet. La plupart des toolkits comme MvvmLight, Prism et les autres proposent tous un service de messagerie qui lave plus blanc.

Toutefois les Xamarin.Forms contiennent à peu près tout ce qu’il faut pour faire du MVVM sans ajouter le moindre toolkit… Le temps passant je n’utilise quasiment plus jamais de toolkit.

Une classe de base pour les ViewModels, un conteneur IoC tel Unity ou autre pour faire de la DI (bien que même là XF propose le sien), et deux ou trois utilitaires et l’affaire est jouée, tout le reste est déjà dans la boîte.

Et qui dit utilisation des Xamarin.Forms au lieu de toolkits externes dit pérennité du code, indépendance vis à vis d’outils tiers, etc. C’est à dire que du bon, et que du raisonnable qui entre d’ailleurs en plein dans la logique MVVM (lé découplage et l’indépendance vis à vis des outils est tout aussi important que le reste).

Certains évoquent pour justifier leurs errements que la messagerie Xamarin.Forms ne serait pas la plus rapide, qu’elle poserait donc des problèmes de performance. Diantre ! Fichtre !

En voilà une belle légende urbaine sortie de nulle part que certains assènent comme une vérité première sans avoir fait le moindre test eux-mêmes ! Et même si on finit par retrouver dans les tréfonds du Web quelques articles qui parlent de la chose, c’est du vieux… que du vieux. Mal ou pas testé en plus. Bref si vous voulez en avoir le cœur … .NET faites le test vous-mêmes dans votre contexte mais arrêtez de propager cette contrevérité.

(la seule vraie référence marquant le début de cette légende est une conférence de Jason Smith à l’Evolve 2016 disant que pour les performances il préfère Prism  – mais lequel… quelle version refaite n fois ? – à la messagerie des XF. Certes Jason n’est pas une bleusaille ni un inconnu, mais sa parole n’est pas non celle d’un demi dieu, il a le droit de se tromper et nous avons le droit de préférer rester collé à ce qu’il y a dans la boîte qui marche très bien !)

J’irai même plus loin… Dans la suite logique de mon introduction où je précise les dangers d’une surutilisation de la messagerie, j’affirme qu’une App qui aurait des problèmes de performances à cause de la messagerie est une App mal architecturée écrite par des pieds.

Si des millions de messages transitent dans tous les sens, oui cela aurait certainement un impact sur les performances, comme tout code exécuté trop souvent… Lapalissade.

Mais si un code en arrive à une telle cadence d’utilisation des messages MVVM c’est que quelque chose ne va pas dans son écriture. De toute façon au moindre problème tout se cassera la figure et ça sera impossible à maintenir. Bon courage pour le debug !

Donc le seul argument contre la messagerie intégrée je viens me semble-t-il de l’exploser avec un scud furtif difficile à contrer…

On peut donc passer au véritable problème, la doc foireuse qui n’incite pas trop à s’en servir.

Une syntaxe ambiguë et surtout … fausse comme la doc !

L’API de la messagerie ressemble à cela :

MessagingCenter.Subscribe<TSender>(object, string, Action<TSender>);
MessagingCenter.Send<TSender>(TSender, string);

On voit le malaise… Il faudrait pour souscrire ou envoyer un message connaître le TSender, donc la classe émettrice. Déjà on comprend mal ce couplage fort que cela oblige et en plus on ne pige rien au message lui-même qui visiblement est soit un Object soit un TSender aussi… Incompréhensible.

En fait tout est clair, si si je vous l’assure !, une fois qu’on a compris que l’erreur était dans le nom arbitraire du générique TSender qui devrait s’appeler TMessage !

Ahhhhh ! Mais là c’est pas pareil ! Ben si, c’est la même API les gars.. juste un alias qu’il faut renommer dans sa tête…

La bonne utilisation

Puisque tout est clair comment utiliser la messagerie alors ? En remplaçant dans sa tête TSender par TMessage…

Envoyer un message ? Facile :

MessagingCenter.Send<LoginMessage>(new LoginMessage, "loginOK");

Souscrire à un message ? Rudimentaire :

MessagingCenter.Subscribe<LoginMessage>(this, "loginOK", (lm) => HandleLogin(lm));

Bon, je vois quelques esprits chagrins qui feront remarquer qu’ici j’utilise directement Send ou Subscribe sans passer par Instance qui est le singleton… Encore un truc louche.

Je l’accorde bien volontiers. Mais si vous regardez le source vous verrez que Send ou les autres méthodes de ce type appellent déjà la fonction interne équivalente en passant par Instance, il est donc inutile de l’invoquer.

Conclusion

Vous voilà éclairé sur les zones d’ombres, pas très grosses il faut l’avouer, qui pouvaient vous empêcher d’utiliser la messagerie des Xamarin.Forms.. Et comme moi au fil du temps vous constaterez que les toolkits  MVVM sauf en de rares occasions ne servent plus à grand chose car tout est déjà dans la boîte ! (et le reste n’est que prise de tête souvent inutile).

Sur ce,

Stay Tuned !

blog comments powered by Disqus