La construction d’une App MAUI utilise un service provider dont l’accès ne semble pas être possible en dehors du code d’initialisation. Or comment l’utiliser pour obtenir un service donné sans passer par l’injection de dépendances dans les constructeurs ?
Accéder à IServiceProvider
Comme vous le savez peut-être, j’assiste mes clients dans la conversion / migration de leur code Xamarin.Forms vers MAUI pour qu'il reste à jour et maintenable. C'est une tâche bien plus importante qu'on ne le pense initialement, d’où l’intérêt de se faire conseiller. Une des difficultés sur laquelle beaucoup buttent est le fait que vous ne pouvez pas accéder au IServiceProvider par défaut de l'application MAUI.
Solutions possibles
Comme toujours, il y a plus d'une solution. Alors que David Ortinau montre une approche dans l'application WeatherTwentyOne qui accède à l’implémentation de la plate-forme des Services, je préfère une autre approche qui utilise l'injection de dépendance pour atteindre le même objectif.
Mise en œuvre
La première chose à faire est de sous-classer Microsoft.Maui.Controls.Application pour fournir un constructeur surchargé où on peut injecter le IServiceProvider utilisé par l'application MAUI. Dans le constructeur on note l’utilisation de la méthode du MVVM CommunityToolkit Ioc.Default.ConfigureServices pour initialiser le handler de l’Ioc de la boîte à outils. Voici le code :
using CommunityToolkit.Mvvm.DependencyInjection;
namespace MauiTestApp
{
public class MyMauiAppImpl : Microsoft.Maui.Controls.Application
{
public MyMauiAppImpl(IServiceProvider services)
{
Ioc.Default.ConfigureServices(services);
}
}
}
Utilisation
L'utilisation de la classe est simple. Ouvrez votre fichier App.xaml et remplacez l’héritage de base par votre application sous-classée (ici MyMauiAppImpl) :
<local:MyMauiAppImpl
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiTestApp"
x:Class="MauiTestApp.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</local:MyMauiAppImpl>
Bien entendu vous devez faire la même chose pour le code behind :
namespace MauiTestApp;
public partial class App : MyMauiAppImpl
{
public App(IServiceProvider serviceProvider) : base(serviceProvider)
{
InitializeComponent();
MainPage = new AppShell;
}
}
Voilà, vous pouvez maintenant utiliser l'implémentation du Ioc.Default du CommunityToolkit MVVM pour accéder aux Services, ViewModels et Views enregistrés.
Conclusion
Dans cet article, je vous ai montré un moyen simple (et même facilement réutilisable) de rendre IServiceProvider disponible dans votre application .NET MAUI. J'ai également indiqué une approche alternative dans le cas où vous voulez pas sous-classer l'objet d'application. Mais ce n’est qu’un exemple de toutes les petites choses qui posent question lors d’une migration d’App ou de bibliothèque de code Xamarin.Forms vers MAUI. Mille et une petites choses à régler mais pas isolément. Un papier de blog ne peut que donner une vision ponctuelle d’un problème. Seul un conseil avisé prenant en compte la totalité de l’application et de son contexte permet de choisir entre chaque alternative celle qui viendra compléter le tableau pour créer un tout harmonieux.
Mais comme toujours, j'espère que cet article sera utile à certains d'entre vous.
Et en attendant le prochain article,
Stay Tuned !