Dot.Blog

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

Prism pour Xamarin.Forms les nouveautés

La version 7.2 de Prism est sortie récemment, faisons le point sur ce qu’il ne fallait pas louper depuis la  7.1…

Des évolutions importantes

Il y a deux ans sortait la version 7.0 de Prism. Le temps a passé et les versions 7.1 et 7.2 sont venues compléter, corriger, améliorer cette release. La 7.2 étant la plus récente (décembre 2019 quand j’écris ce papier qui est prévu en parution pour fin janvier 2020).

Il est ainsi temps de faire un point sur les changements intervenus car certains peuvent être troublants (breaking changes).

Ajouts de la version 7.1

Quand je parle de version 7.1, comme pour la version 7.2 d’ailleurs, je parle de l’ensemble des releases sous ce numéro de version jusqu’à la dernière publiée, il y a eu des intermédiaires entre 7.1et 7.2 et entre la première 7.2 et aujourd’hui il y en a eu d’autres.

Ceci étant précisé voici le premier breaking change d’importance surtout si vous avec upgradé depuis la 7.0 en toute confiance ou si vous vous apprêtez à le faire:

INavigationParameters à la place de NavigationParalmeters

Le type des paramètres de navigation a été modifié pour laisser la place à une Interface, créant une isolation plus conforme à l’esprit MVVM.

De fait le code passe de celui du haut à celui du bas :

image

image

Pas de quoi s’inquiéter mais un code 7.0 donnera des erreurs de compilation (se corrigeant facilement malgré tout).

Navigation “hors sol”

Le concept est intéressant et vous l’avez peut-être loupé, mais la version 7.1 a introduit la possibilité de naviguer en XAML sans même avoir besoin d’un ViewModel !

Après tout pourquoi pas, cela peut avoir une utilité (rare me semble-t-il).

L’accès à cette fonctionnalité s’effectue en deux étapes :

L’ajout du namespace particulier

image

Nommer la page destination dans le binding d’une propriété Command

image

ce qui va donner un code complet de ce type là (imaginons une page ContentPage avec juste un bouton dessus) :

image

Si cela vous rend service n’hésitez pas à le dire dans les commentaires et surtout dans quel contexte cela vous sert.. Je reste perplexe personnellement mais pour une AboutBox peut-être ? Attention en tout cas de ne pas interférer avec le nouveau SHELL !

Injection de dépendances dans les ValueConverters (et autres types)

On retrouve bien là l’esprit originel de Prism, rendre tout plus compliqué même si cela est fait avec intelligence et “pour le bien” du développeur… Seulement à la fin la prise en main de la toolbox Mvvm devient un enfer… Mais bon, c’est fait c’est fait… Et c’est plutôt intéressant d’ailleurs.

Le fournisseur de conteneur IoC autorise maintenant à ajouter des types comme ValueConverters pour les inclure dans le processus d’injection de dépendance.

Même si cela complexifie l’apprentissage de Prism et sa bonne application au sein d’équipes hétérogènes (ce que je reprochais comme d’autres à Prism pour WPF d’où mon conseil d’utiliser MvvmLight à l’époque, moins complet mais assurément compris par tous), il faut convenir que l’ajour est intelligent. Par exemple admettons qu’on veuille changer la couleur d’un élément selon qu’on soit sur Tablette ou Smartphone. Prism fournit déjà un service IDeviceService pour le savoir. Il suffit alors de connecter un convertisseur de valeur à la propriété couleur en question, à jouter le convertisseur au conteneur IoC et laisser faire Prism…

image

On remarquera le paramètre IDeviceService dans le constructeur du IValueConverter… Prism injectera son service, le convertisseur pour savoir sur quel matériel il se trouve et pourra retourner la couleur en fonction de la situation, le tout sans intervention manuelle, sans bricolage de code behind, etc..

On peut bien entendu utiliser ce genre d’astuce dans beaucoup d’autres circonstances (on peut aussi utiliser des dictionnaires de style pour les couleurs plutôt que de retourner des valeurs en dur comme dans l’exemple ci-dessus !).

Pour utiliser l’astuce en XAML il faut invoquer le ContainerProvider de la sorte :

image

Aussi subtile que cela soit je m’imagine mal faire gober ce genre de construction en quelques jours de formation, sauf à débiter un cours en se fichant de savoir s’il a été compris et comment il sera appliqué une fois qu’on aura tourné les talons… Prism revient à sa sophistication première c’est génial techniquement, les amateurs de toolbox ultra riche seront contents tout comme ceux qui maîtrisent déjà MVVM sur le bout des doigts. Mais ayons une pensée pour ceux qui doivent se former à ce genre de choses…

Ajouts de la version 7.2

Cette version récente apporte son petit paquet de nouveautés et pas des moindres. Couche après couche on revient à ce je disais quelques lignes plus haut sur la complexification de la toolbox et de l’aléatoire que cela entraîne sur sa bonne utilisation par des équipes hétérogènes.

Conflit chez les aiguilleurs du ciel… AutoRegistrationForNavigation

C’est bien joli de fournir tout un tas de trucs pour la navigation mais comme Xamarin a sorti récemment le Shell qui modifie le paradigme de navigation, toutes les toolbox comme Prism sont prises en défaut car aucune ne s’est adaptée pour l’instant à cette nouvelle façon de naviguer. Et Prism par exemple continue de peaufiner son propre système de navigation dans l’ignorance la plus totale du Shell. On a deux avions qui se dirigent l’un vers l’autre, belle image de convergence ? non… annonce d’un drame ! Car pour le développeur c’est aujourd’hui un affreux casse-tête ! Optez pour la navigation de Prism en se fichant complètement de l’avancée qu’est Shell ou bien adopter Shell et laisser tomber tous les avantages de Prism dans le domaine de la navigation ?

Personnellement si je dois trancher pour lancer un nouveau projet je trancherai, c’est mon job d’architecte, en tentant d’apporter la réponse la plus cohérente en fonction du client concerné et de l’App à créer, mais je sera sacrément soulagé quand les toolbox prendront en compte Shell ! D’où mon conseil toujours valable d’utiliser la toolbox la plus minimaliste pour éviter un sac de nœud à la fin… J’adore Prism depuis toujours mais dans ce genre de situation intermédiaire on comprend pourquoi conduire un semi-remorque est tout de même moins pratique qu’une Fiat 500 si on doit faire ses courses dans les rues étroites de la ville…

Sinon l’astuce est plutôt bien vue, si je peux me permettre, puisque tant qu’on suit une convention (généralement admise par tout le monde) dans le nommage des Vues et des ViewModels on voit mal pourquoi le lien ne se ferait pas automatiquement…

Pourquoi écrire un code comme :

image

Alors que désormais on peut juste ajouter un Attribut pour que dans toute l’application le lien View/ViewModels soit automatisé…

image

la convention exploitée est celle que nous utilisons normalement tous déjà : Nom de Page + ViewModel pour les ViewModels. Ainsi la page “LoginPage” devra avoir un ViewModel nommé “LoginPageViewModel”, le mot “Page” n’est pas supprimé du nom de la page. Je trouve cela dommage. Mais avouez que c’est pratique. La création d’une page entraînera la création et le lien du ViewModel sans aucun code à écrire.

Simplification des paramètres de Navigation

Jusqu’à lors pour envoyer des paramètres à un autre ViewModel durant une navigation il fallait créer une nouvelle instance de NavigationParameters et l’initialiser correctement avant de la passer à NavigateAsync.

Désormais on peut tout en faire en une seule ligne pour naviguer tout en passant des paramètres :

image

En revanche cet ajout intéressant s’accompagne de dommages collatéraux come l’obsolescence non pas programmée mais programmatique de l’utilisation de INavigationAware pour recevoir des paramètres.

Donc plutôt que d’écrire

image

On écrira désormais

image

Avec une nouvelle subtilité (once more) le support de l’asynchrone en utilisant IInitializeAsync à la place de IInitialize tout court

image

Voilà de quoi donner de belles nuits blanches à celui qui doit prendre en main tout ça alors qu’il débarque dans une équipe qui serait déjà bien rodée…

Coucou les Popup !

Grâce au service pré-enregistré IDialogService on peut désormais (enfin !) afficher des dialogues. Pour utiliser cette nouvelle facilité il suffit d’implémenter un ViewModel qui supporte IDialogAware.

image

Bien entendu il faut créer la Vue généralement en partant du type Frame et contenant tout ce qu’on veut afficher dans le dialogue. On n’oubliera pas (ancienne façon) d’enregistrer le couple Vue / ViewModel ou bien de respecter la convention de nommage pour un lien automatique (nouvelle façon de procéder expliquée plus haut).

Je n’entrerai pas plus dans les détails, ce n’est pas le but de ce papier, mais on peut bien entendu passer des paramètres et en recevoir pour … dialoguer avec le Dialogue !

Paramètres automatiques

Encore une avancée indéniable pour qui pratique déjà tout Prism avec assurance depuis un moment mais qui complique encore un peu plus le tableau pour les nouveaux arrivants…

L’interface IAutoInitialize s’utilise maintenant pour passer des paramètres automatiquement pour peu qu’on puisse leur donner un nom qui corresponde au nom de la propriété dans le ViewModel récepteur.

Personnellement je n’aime pas ça du tout. J’admire le côté pratique, mais le fait d’avoir à connaître le nom d’une propriété d’un autre ViewModel me hérisse le poil d’autant que le passage du paramètre se fait en string, bonjour les bugs en cas de refactoring… je déconseille vivement cette astuce donc. Même si elle est sympa.

On peut donc écrire maintenant :

image

Il y a même plus fort et plus subtile, on peut rendre le passage du paramètre obligatoire. S’il n’est pas passé la navigation sera refusée. il suffit d’ajouter l’attribut [AutoInitialize(true)] devant la déclaration de la propriété (ici “Message”).

Conclusion

Après une pause, le “syndrome Prism” revient en force… Toujours plus de subtilité, donc de complexité. C’est génial j’adore cette toolbox depuis WPF mais paradoxalement je la déconseille à la plupart de mes clients. J’avais fait une pause dans les premières version pour Xamarin.Forms qui me semblaient se maintenir dans le raisonnable. Mais une fois les bases posées ces diables n’ont pu s’empêcher de revenir à leur dada favori, rendre plus complexe quelque chose qui devrait rester simple…

Prism devient donc de mieux en mieux, il faut s’en réjouir. Mais en même temps le ticket d’entrée de son apprentissage devient plus cher. Plus cher en formation, en post formation, en auto formation, en bogues inévitables que feront ceux qui ne maîtrisent pas tout parfaitement…

Donc je réitère mes conseils de l’époque de WPF : oui mille fois à Prism pour un développeur seul bien formé, pour une équipe de dev ultra soudée et de niveau homogène. Non autant de fois pour les équipes hétérogènes, les développeurs pas encore à l’aise avec tous les concepts de Mvvm. Pour eux mieux vaut une toolbox moins sophistiquée comme MvvmLight ou FreshMvvm, certes limitées l’une et l’autre, mais qui ne favoriseront pas les erreurs très couteuses en fin de course, la fameuse Dette Technique qui s’entasse à chaque ligne de code écrite…

Pour d’autres nouvelles…

Stay Tuned !

Faites des heureux, PARTAGEZ l'article !