Xamarin.Forms Inscription et résolution de DependencyService

Télécharger l’exemple Télécharger l’exemple

Lorsque vous utilisez pour appeler la Xamarin.FormsDependencyService fonctionnalité de plateforme native, les implémentations de plateforme doivent être inscrites auprès du DependencyService, puis résolues à partir du code partagé pour les appeler.

Inscrire des implémentations d’une plateforme

Les implémentations de plateforme doivent être inscrites auprès de afin DependencyService de Xamarin.Forms pouvoir les localiser au moment de l’exécution.

L’inscription peut être effectuée avec les DependencyAttributeméthodes ou avec les Register méthodes et RegisterSingleton .

Important

Les versions Release des projets UWP qui utilisent la compilation native de .NET doivent inscrire les implémentations de plateforme avec les méthodes Register.

Inscription par attribut

Vous pouvez utiliser DependencyAttribute pour inscrire une implémentation de plateforme auprès de DependencyService. L’attribut indique que le type spécifié fournit une implémentation concrète de l’interface.

L’exemple suivant utilise pour DependencyAttribute inscrire l’implémentation iOS de l’interface IDeviceOrientationService :

using Xamarin.Forms;

[assembly: Dependency(typeof(DeviceOrientationService))]
namespace DependencyServiceDemos.iOS
{
    public class DeviceOrientationService : IDeviceOrientationService
    {
        public DeviceOrientation GetOrientation()
        {
            ...
        }
    }
}

Dans cet exemple, DependencyAttribute inscrit DeviceOrientationService auprès de DependencyService. Ce qui aboutit à l’inscription du type concret auprès de l’interface qu’il implémente.

De même, les implémentations de l’interface IDeviceOrientationService sur d’autres plateformes doivent être inscrites avec DependencyAttribute.

Notes

L’inscription avec DependencyAttribute est effectuée au niveau de l’espace de noms.

Inscription par méthode

Les DependencyService.Register méthodes et la RegisterSingleton méthode peuvent être utilisées pour inscrire une implémentation de plateforme avec .DependencyService

L’exemple suivant utilise la Register méthode pour inscrire l’implémentation iOS de l’interface IDeviceOrientationService :

[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();
        LoadApplication(new App());
        DependencyService.Register<IDeviceOrientationService, DeviceOrientationService>();
        return base.FinishedLaunching(app, options);
    }
}

Dans cet exemple, la méthode Register inscrit le type concret DeviceOrientationService auprès de l’interface IDeviceOrientationService. Vous pouvez aussi utiliser une surcharge de la méthode Register pour inscrire une implémentation de plateforme auprès de DependencyService :

DependencyService.Register<DeviceOrientationService>();

Dans cet exemple, la méthode Register inscrit DeviceOrientationService auprès de DependencyService. Ce qui aboutit à l’inscription du type concret auprès de l’interface qu’il implémente.

Vous pouvez également inscrire un objet instance existant en tant que singleton avec la RegisterSingleton méthode :

var service = new DeviceOrientationService();
DependencyService.RegisterSingleton<IDeviceOrientationService>(service);

Dans cet exemple, la RegisterSingleton méthode inscrit l’objet DeviceOrientationService instance sur l’interfaceIDeviceOrientationService, en tant que singleton.

De même, les implémentations de l’interface IDeviceOrientationService sur d’autres plateformes peuvent être inscrites auprès des Register méthodes, ou de la RegisterSingleton méthode .

Important

L’inscription avec les Register méthodes et RegisterSingleton doit être effectuée dans les projets de plateforme, avant que les fonctionnalités fournies par l’implémentation de la plateforme soient appelées à partir du code partagé.

Résoudre les implémentations d’une plateforme

Les implémentations d’une plateforme doivent être résolues avant d’être appelées. Cette opération est généralement effectuée dans du code partagé avec la méthode DependencyService.Get<T>. Cependant, cette opération peut aussi être effectuée avec la méthode DependencyService.Resolve<T>.

Par défaut, DependencyService résout uniquement les implémentations de plateforme qui ont des constructeurs sans paramètre. Toutefois, une méthode de résolution des dépendances peut être injectée dans Xamarin.Forms qui utilise un conteneur d’injection de dépendances ou des méthodes de fabrique pour résoudre les implémentations de plateforme. Cette approche permet de résoudre les implémentations de plateforme qui ont des constructeurs avec des paramètres. Pour plus d’informations, consultez Résolution des dépendances dans Xamarin.Forms.

Important

L’appel d’une implémentation de plateforme qui n’a pas été inscrite auprès de DependencyService entraîne la levée d’une NullReferenceException.

Résoudre avec la méthode Get<T>

La Get<T> méthode récupère l’implémentation de la plateforme de l’interface T au moment de l’exécution, et soit :

  • Crée une instance de celui-ci en tant que singleton.
  • Retourne un instance existant en tant que singleton, qui a été inscrit avec la DependencyServiceRegisterSingleton méthode by.

Dans les deux cas, le instance sera actif pendant toute la durée de vie de l’application, et tous les appels suivants pour résoudre la même implémentation de plateforme récupéreront la même instance.

Le code suivant montre un exemple d’appel de la méthode Get<T> pour résoudre l’interface IDeviceOrientationService, puis d’un appel de sa méthode GetOrientation :

IDeviceOrientationService service = DependencyService.Get<IDeviceOrientationService>();
DeviceOrientation orientation = service.GetOrientation();

Vous pouvez aussi condenser ce code sur une seule ligne :

DeviceOrientation orientation = DependencyService.Get<IDeviceOrientationService>().GetOrientation();

Notes

La Get<T> méthode retourne une instance de l’implémentation de la plateforme de l’interface T en tant que singleton, par défaut. Vous pouvez cependant changer ce comportement. Pour plus d’informations, consultez Gérer la durée de vie des objets résolus.

Résoudre avec la méthode Resolve<T>

La Resolve<T> méthode récupère l’implémentation de la plateforme de l’interface T au moment de l’exécution, à l’aide d’une méthode de résolution de dépendances qui a été injectée dans Xamarin.Forms la DependencyResolver classe . Si une méthode de résolution de dépendance n’a pas été injectée dans Xamarin.Forms, la Resolve<T> méthode sera de secours pour appeler la Get<T> méthode pour récupérer l’implémentation de la plateforme. Pour plus d’informations sur l’injection d’une méthode de résolution de dépendance dans Xamarin.Forms, consultez Résolution des dépendances dans Xamarin.Forms.

Le code suivant montre un exemple d’appel de la méthode Resolve<T> pour résoudre l’interface IDeviceOrientationService, puis d’un appel de sa méthode GetOrientation :

IDeviceOrientationService service = DependencyService.Resolve<IDeviceOrientationService>();
DeviceOrientation orientation = service.GetOrientation();

Vous pouvez aussi condenser ce code sur une seule ligne :

DeviceOrientation orientation = DependencyService.Resolve<IDeviceOrientationService>().GetOrientation();

Notes

Lorsque la Resolve<T> méthode revient à appeler la Get<T> méthode, elle retourne une instance de l’implémentation de la plateforme de l’interface T en tant que singleton, par défaut. Vous pouvez cependant changer ce comportement. Pour plus d’informations, consultez Gérer la durée de vie des objets résolus.

Gérer la durée de vie des objets résolus

Le comportement par défaut de la classe DependencyService est de résoudre les implémentations de plateforme en tant que singletons. Par conséquent, les implémentations de plateforme vont perdurer pendant toute la durée de vie d’une application.

Ce comportement est spécifié avec l’argument facultatif DependencyFetchTarget sur les méthodes Get<T> et Resolve<T>. L’énumération DependencyFetchTarget définit deux membres :

  • GlobalInstance, qui retourne l’implémentation de plateforme en tant que singleton.
  • NewInstance, qui retourne une nouvelle instance de l’implémentation de la plateforme. L’application est alors responsable de la gestion de la durée de vie de l’instance de l’implémentation de la plateforme.

Les méthodes Get<T> et Resolve<T> définissent leurs arguments facultatifs sur DependencyFetchTarget.GlobalInstance, et les implémentations de plateforme sont donc toujours résolues en tant que singletons. Vous pouvez changer ce comportement de façon à créer les nouvelles instances des implémentations de plateforme en spécifiant DependencyFetchTarget.NewInstance comme arguments des méthodes Get<T> et Resolve<T> :

ITextToSpeechService service = DependencyService.Get<ITextToSpeechService>(DependencyFetchTarget.NewInstance);

Dans cet exemple, DependencyService crée une nouvelle instance de l’implémentation de la plateforme pour l’interface ITextToSpeechService. Tous les appels suivants pour résoudre ITextToSpeechService vont également créer de nouvelles instances.

La conséquence de la création systématique d’une nouvelle instance d’une implémentation de plateforme est que l’application devient responsable de la gestion de la durée de vie des instances. Cela signifie que si vous vous abonnez à un événement défini dans une implémentation de plateforme, vous devez vous désabonner de l’événement quand l’implémentation de plateforme n’est plus nécessaire. Cela signifie aussi que les implémentations de plateforme devront éventuellement implémenter IDisposable et nettoyer leurs ressources dans les Dispose. L’exemple d’application illustre ce scénario dans ses implémentations de plateforme TextToSpeechService.

Quand une application a fini d’utiliser une implémentation de plateforme qui implémente IDisposable, elle doit appeler l’implémentation Dispose de l’objet. Ceci peut être effectué avec une instruction using :

ITextToSpeechService service = DependencyService.Get<ITextToSpeechService>(DependencyFetchTarget.NewInstance);
using (service as IDisposable)
{
    await service.SpeakAsync("Hello world");
}

Dans cet exemple, après l’appel de la méthode SpeakAsync, l’instruction using supprime automatiquement l’objet d’implémentation de plateforme. Le résultat est que la méthode Dispose de l’objet est appelée, qui effectue le nettoyage nécessaire.

Pour plus d’informations sur l’appel de la méthode Dispose d’un objet, consultez Utilisation d’objets qui implémentent IDisposable.