Dot.Blog

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

Le Code Generator du Community.Toolkit.Mvvm pour MAUI

Je vous ai déjà présenté longuement le Community Toolkit MVVM, restait la feature de génération automatique de code qui n’était pas encore prête à l’époque. Voici de quoi il s’agit…

CommunityToolkit.Mvvm

Déjà présenté dans une série de 5 papiers (liens ci-dessous) le Toolkit MVVM appartient au Community Toolkit mais s’installe à part (pour ne pas surcharger le code des Apps qui utilisent un autre toolkit).

Livre gratuit

Dans la tradition de Dot.Blog les lecteurs peuvent aussi télécharger un livre de 30 pages A4 présentant à la fois le Community Toolkit MVVM et certains aspects comparatifs importants (le CT vs MVVM Light ou Prism par exemple).

Vous le trouverez à cette adresse : https://www.e-naxos.com/Download/CommunityToolkitMVVM.pdf

Génération automatique de code

À partir de la version 8.0, la boîte à outils MVVM comprend de tout nouveaux générateurs de source Roslyn qui aident à réduire considérablement le temps de mise en place lors de l'écriture de code à l'aide de l'architecture MVVM. Ils peuvent simplifier les scénarios dans lesquels vous devez configurer des propriétés observables, des commandes, etc. Voici une vue simplifiée du fonctionnement des générateurs de source Roslyn :

 

C’est donc une feature totalement nouvelle. Comme je l’ai expliqué ce toolkit a été créé pour prendre la place de Mvvm.Light que son auteur a arrêté de supporter. Mais avant de tirer sa révérence il a aidé l’équipe a reprendre l’essentiel de Mvvm.Light pour que la transition soit la plus simple. On dispose donc d’un noyau que les utilisateurs de Mvvm.Light ne devrait avoir aucun mal à prendre en main. Mais bien entendu tout a été réécrit et l’équipe du CT a reformuler les bonnes idées d’hier avec les technologies d’aujourd’hui, ajoutant au passage des features qui font du nouveau toolkit un ensemble neuf et innovant, et pas seulement un repompage de Mvvm.Light. 

Par exemple la fonction de génération automation de code est l’une de ces features qui change la donne et qui était totalement absente de Mvvm.Light. Mais de quoi s’agit-il ?

Tout d'abord, vous n'avez pas besoin d'implémenter INotifyPropertyChanged dans vos ViewModels. Et j'entends par là même pas ses classes parentes. Puisque ce toolkit est un générateur de code, il suffit de rendre vos classes partielles, et l'implémentation INotifyPropertyChanged est faite par lui, au lieu de vous. Cela signifie que la classe sera complétée par la meilleure implémentation afin que vous puissiez facilement utiliser des méthodes courantes comme SetProperty dans la branche setter de vos propriétés. D'accord, d'accord, mais presque n'importe quel framework MVVM peut le faire, et vous n'avez même pas besoin d'utiliser un générateur de code, dérivez simplement d'une classe parent, un ViewModel de base et l’affaire est jouée non ? Ok, pas faux. Mais j’ai mieux à vous proposer : et si vous n'aviez pas du tout à écrire les branches setter et getter des propriétés ? Et si la boîte à outils les fabriquait elle-même ? Si vous pouviez implémenter une déclaration de propriété à partir de deux lignes de code ?

Eh bien, c'est ce qui fait la qualité de cette boîte à outils : elle fait tout cela pour vous. Et ça change d’un simple héritage d’un ViewModel de base (ce qui reste possible mais pour d’autres besoins éventuels).

Et si cela ne suffit pas, vous n'avez même pas à vous soucier de créer des commandes. La boîte à outils crée automatiquement une commande pour vous à partir de vos méthodes.

Mais voyons comment vous pouvez l'utiliser via un court exemple (le reste est à piocher dans la doc du toolkit).

CommunityToolkit.MVVM sous .NET MAUI

Voyons à quoi ressemble le ViewModel exemple (donc en écriture "normale") avant d'utiliser le toolbox :

namespace ViewModels.SignInPage
{
    public partial class SignInPageViewModel : BaseViewModel
    {
        private Command signInCommand;
        public Command SignInCommand
        {
            get { return signInCommand ?? (signInCommand = new Command(() => _ = SignIn(), () => true)); }
        }
 
        private string userName;
        public string UserName
        {
            get { return userName; }
            set { SetProperty(ref userName, value, nameof(UserName)); }
        }
 
        private string password;
        public string Password
        {
            get { return password; }
            set { SetProperty(ref password, value, nameof(Password)); }
        }
 
        public SignInPageViewModel()
        {
 
        }
 
        private void SignIn()
        {
            try
            {
                ...
            }
            catch (Exception ex)
            {
                // todo error
            }
        }
    }
}


C’est un viewModel très classique avec des propriétés, des commandes, des données… Mais pour très peu de choses au final il reste assez verbeux. Plus de 40 lignes de code.

Utilisons maintenant la génération de code automatique du CT MVVM :

Namespace ViewModels.SignInPage
{
    [INotifyPropertyChanged]
    public partial class SignInPageViewModel
    {
        [ObservableProperty]
        private string userName;
 
        [ObservableProperty]
        private string password;
 
        public SignInPageViewModel()
        {
 
        }
 
        [ICommand]
        private void SignIn()
        {
            try
            {
                ...
            }
            catch (Exception ex)
            {
                // todo error
            }
        }
    }
}


Une poignée d’attributs et presque plus rien à écrire en étant sûr et certain que cela va marcher sans bug… 

Mais on pourrait là aussi se dire que finalement des outils comme Resharper savent plus ou moins aider à écrire du code de ce type. Oui mais attendez ! Et si maintenant nous avons besoin de « prévenir » une autre propriété du changement de l’une d’entre-elles ? Oui, il existe un attribut pour cela :

[ObservableProperty]
[AlsoNotifyFor(nameof(CanSignIn))]
private string _userName;
 
[ObservableProperty]
[AlsoNotifyFor(nameof(CanSignIn))]
private string _password;
 
 
public bool CanSignIn { get => !string.IsNullOrWhiteSpace(UserName) 
                               && !string.IsNullOrWhiteSpace(Password); }


Et voilà… 

S’agissant d’une fonctionnalité nouvelle au moment où j’écris cet article (oui, j'écris les articles à l'avance donc il y a parfois quelques mois de décalage !) je vous conseille vivement de vous intéresser à la documentation qu’on trouve ici : https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/generators/overview 

Conclusion

Un bon toolkit MVVM c’est déjà appréciable. Mais lorsqu’il ajoute à sa palette de fonctions et services la génération de code automatique cela devient réellement un avantage stratégique et tactique de l’utiliser : gain de temps, de productivité, diminution de la dette technique, augmentation de la fiabilité… On a tout à y gagner ! 

Stay Tuned !



blog comments powered by Disqus