Faire un Hello World c’est sympa, mais faire un tour plus
réaliste incluant le testing et le reste c’est encore plus sympa !
Suivez-moi pour une série / cours de 5 papiers autour d’une App, de A à Z
Plus loin qu’un Hello World
Au début de cette saga sur MAUI je vous ai montré l’inévitable
Hello World (ref papier #3 23/9/22), il fallait bien se mettre en jambes. Mais
si on allait un peu plus loin ? Par exemple en voyant tous les aspects
d’une App réelle, mais tout en restant simple.
Un cours presque complet. Il ne
sera pas possible de tout voir en détail, mais cette série en 5 épisodes est en
réalité un mini cours plutôt complet qui abordera tous les aspects essentiels
de la création d’un projet MAUI réaliste. MVVM, l’injection de dépendance, les
tests unitaires, etc, nous verrons tout cela et bien plus encore. Alors
accrochez vos ceintures, on décolle !
Le projet de base
Le point de départ de notre saga est bien entendu la création
d’un projet MAUI utilisant le template par défaut fourni par Microsoft. Pour
cela pas de redite inutile je vous renvoie aux articles précédents ainsi qu’à
celui consacré à l’Hello World, on ne va pas le refaire ici, c’est quelque
chose d’acquis. Je renvoie ainsi ceux qui aurait loupé cet épisode au papier du
Hello World.
Passer la vitesse supérieure
Bon, nous avons notre projet de base mais c’est assez peu
réaliste, il marche, il fait des choses (le compteur qui s’incrémente) mais il
ne respecte pas les bonnes pratiques et est trop simple pour prétendre être un
Hello World véritablement sérieux.
Il nous manque plein de choses. Mais on va garder un code
ultra simple pour chacune. C’est plutôt la structure générale et les bonnes
pratiques que nous allons voir pour créer un « projet zéro ». Par
exemple il nous manque tout ce qui concerne MVVM, ou bien le Unit Testing. Bref
ce qui est nécessaire pour se rapprocher un peu plus d’une véritable App MAUI.
Je ne vous parlerai pas de tout à la fois, bien d’autres articles viendront
compléter ce premier pas, déjà ceux de la série lancée aujourd’hui de 5
billets, puis tous ceux à venir et même tous ceux déjà existant !
MVVM
Je parlais de MVVM à l’instant et de papiers déjà écrits…
coïncidence (ou pas) j’en ai écrit plein sur ce sujet notamment les récents sur
le Microsoft MVVM Toolkit (série
en 5 parties) et beaucoup d’autres avant traitant de ce sujet, et même de
la comparaison
entre MVVM et MVU dont vous avez peut-être entendu parlé dans le cadre de
MAUI… Tous ces articles sont tagués MVVM dans Dot.Blog et pour en voir toute la
liste il suffit de cliquer sur ce lien https://www.e-naxos.com/Blog/?tag=/mvvm
.

Pour les paresseux qui ne veulent pas tout reprendre à zéro
(il a tout de même environ 70 articles dans Dot.Blog tagués MVVM !!!)
voici en quelques mots de quoi il s’agit :
Dans une App bien écrite nous devons séparer notre code pour
améliorer la maintenance et les tests (plus d'informations sur les tests dans cette
série de 5 articles). Un pattern très utilisé dans le monde C#/XAML est MVVM
né à l’époque de WPF et qui a connu des tas d’implémentations différentes dans
des Toolkits célèbres comme Mvvm Light, Caliburn, Prism et bien d’autres. Ce
pattern assez proche de Model-View-Controller (MVC), et qui signifie
Model-View-ViewModel, nous dit que :
- Le Modèle (Model, le premier M de MVVM) contient nos
informations brutes sur le domaine qui peuvent provenir de diverses sources de
données et nos règles métier.
- Le ViewModel (le second V et le dernier M de MVVM) récupère
généralement le Modèle via un service pour assurer encore plus l’isolation du
code. Le ViewModel prépare ensuite les informations à afficher et réagit
aux commandes de l’utilisateur qui lui sont passées par la Vue. Il contient
donc la « glu » entre le Modèle et la Vue, c’est-à-dire la gestion
des flux de données entre ces deux pôles et celle des interactions avec
l’utilisateur.
- La Vue (View, le premier V de MVVM) affiche ce qui se trouve
dans le ViewModel et transmet les interactions de l’utilisateur à ce dernier.
La séparation des préoccupations ici est
que
- La Vue ne sait pas comment le ViewModel obtient ses
informations.
- Le ViewModel ne sait pas comment le Model obtient ses
informations.
- Le ViewModel ne sait pas quelle Vue lui est connectée.
- La Vue ne peut pas contenir de code ni de règles métier.
Elle ne peut contenir que du code lié à l’UI.
- Le ViewModel ni le Modèle ne peuvent intervenir sur l’UI.
Cela nous permet d'apporter des modifications de code à la Vue,
au ViewModel et au Modèle de façon indépendante autorisant des équipes
différentes à travailler sur chacune de ces parties sans risque de bogues et
cela facilite grandement le Unit Testing de chaque partie.
Au départ l’idée était surtout de
séparer la partie UI de la partie code proprement dit, donc d’un côté des
graphistes construisant l’UI et de l’autre des développeurs créant le code.
Naissait un nouveau métier, Intégrateur, un développeur un minimum doué pour
l’UI qui s’occupait de brancher tout cela. C’était un schéma idyllique jamais
appliqué dans la réalité en raison du profil incongru de l’Intégrateur (qui dit
rare dit cher et les patrons n’aiment pas ça…). Mais des débuts de MVVM il nous
reste surtout aujourd’hui l’idée principale d’un couplage lâche. Ce
dernier concernant autant le code que les Vues, les ViewModels, les Modèles,
les Services, etc.
Un aspect important de MVVM est ainsi de savoir comment lier
les champs de la Vue au ViewModel car le circuit de l’information n’est pas
unidirectionnel. L'utilisateur interagit avec la vue, par exemple en
cliquant sur un bouton pour incrémenter un compteur. Cela met à jour les
données stockées dans le ViewModel (et éventuellement transmises au Modèle).
Cependant, nous pouvons également mettre à jour les valeurs
par programmation directement dans le ViewModel, et nous voulons que ces valeurs
s'affichent dans la vue. Il s'agit d'une liaison bidirectionnelle. Autre
situation semblable : le Modèle peut changer (un SGBD, un capteur de
smartphone…) et ce changement doit être reflété par la Vue. D’ailleurs dans sa
version « souple » MVVM autorise une Vue à se connecter directement à
un Modèle sans passer par un ViewModel s’il n’y a aucune interaction de
l’utilisateur. Ce cas est très rare et bien entendu dans une App bien
structurée toutes les Vues utilisent un ViewModel même s’il est vide (ce qui
est exceptionnel donc).
Pour assurer ce découplage fort dans nos projets nous
n’allons pas réinventer la roue à chaque fois. Et même au sein d’un même projet
de nombreuses choses vont devenir répétitives. Pour cela XAML nous offre un
système de liaison de données (Data Binding) puissant. Mais ce n’est pas assez
pour assurer une couverture totale de MVVM. Il nous faut ainsi un Toolkit qui
va proposer tout le nécessaire. Il y a eu beaucoup de ces Toolkits dans
l’histoire de XAML, celui que nous allons utiliser avec MAUI est le Microsoft
MVVM Toolkit. Il a été conçu pour remplacer Mvvm Light qui était le plus
utilisé, tout en le rendant plus performant et plus moderne (avec l’aide de son
créateur qui a participé aux premiers pas du Toolkit Microsoft).
Bien entendu dans cette petite série de 5 billets pour
réaliser un Hello World plus réaliste nous allons balayer plein de concepts
comme MVVM, il n’est pas possible de détailler chacun. Même la séparation en 5 parties
ne le permet pas. Je renvoie donc le lecteur aux articles déjà écrits sur le
sujet, de façon générale ou spécifique (comme la présentation du Toolkit
Microsoft).
Ajouter un ViewModel
Cette digression autour de MVVM nous amène en toute logique
à l’ajout d’un ViewModel à notre App de base (celle créée au départ par le
template de Visual Studio).
Que fait l’App pour le moment ? Pas grand-chose c’est
certain, mais c’est un Hello World… Quand l’utilisateur clique sur le bouton,
le compteur est incrémenté, ce que la Vue reflète.
Nota : le code source zippé
sera diffusé avec l’épisode 3 ainsi que le 5.
Comment le fait-elle ? Mal ! Et doublement
même ! D’une part la Vue connecte l’évènement du clic du bouton
directement à son propre code behind (MainPage.xaml.cs), d’autre part ce
code agit directement sur la Vue sans passer par un ViewModel. Mais ce n’est
qu’un template.
Il nous faut avant toute autre chose casser ce couplage fort
entre l’UI et le code, donc ajouter un ViewModel. Ce dernier va être construit
avec les briques fournies par le Microsoft MVVM Toolkit.
Pour commencer il faut ajouter le paquet du Toolkit à notre
projet.
On notera que le Microsoft.Toolkit.Mvvm,
au départ isolé, a été intégré au Community Toolkit, toutefois il reste
sous la forme d’un paquet séparé car chacun peut choisir d’utiliser un autre
Toolkit MVVM sans pour autant se passer des services du Community Toolkit ni
avoir deux Toolkits MVVM dans l’App dont l’un ne servirait pas…
C’est donc aujourd’hui le paquet CommunityToolkit.Mvvm
qu’il faut ajouter au projet.
Vous savez ajouter un paquet à un projet, je vais vous
laisser faire on gagnera un peu de temps.
