Xamarin.Forms之DependencyService

DependencyService 类是允许 Xamarin.Forms 应用程序从共享代码 调用本机平台功能的服务定位器。

必须使用 DependencyService 注册平台实现,然后从共享代码进行解析,才能调用它们。

DependencyService的理由: 由于 Xamarin.Forms 不包含此功能,因此有必要使用 DependencyService 来访问每个平台上的本机 API

介绍

使用 DependencyService 调用本机平台功能的过程用于:

  1. 在共享代码中创建本机平台功能的接口。 有关详细信息,请参阅创建接口。
  2. 在所需的平台项目中实现此接口。 有关详细信息,请参阅在各个平台上实现接口。
  3. 通过 DependencyService 注册平台实现,这样 Xamarin.Forms 即可以在运行时找到平台实现。 有关详细信息,请参阅注册平台实现。
  4. 从共享代码解析平台实现,并调用它们。 有关详细信息,请参阅解析平台实现。

下图说明了如何在 Xamarin.Forms 应用程序中调用本机平台功能:

使用 Xamarin.Forms DependencyService 类执行服务定位概述

 

1、创建接口

若要能够从共享代码调用本机平台功能,第一个步骤是创建接口来定义与本机平台功能交互的 API。 应将此接口置于共享代码项目中。

下面的示例说明了可用于检索设备方向的 API 接口:

public interface IDeviceOrientationService
{
    DeviceOrientation GetOrientation();
}

2、在各个平台上实现此接口

创建定义与本机平台功能交互的 API 的接口后,必须在各个平台项目中实现此接口。

Android

下面的代码示例演示 Android 上的 IDeviceOrientationService 接口实现:

namespace DependencyServiceDemos.Droid
{
    public class DeviceOrientationService : IDeviceOrientationService
    {
        public DeviceOrientation GetOrientation()
        {
            IWindowManager windowManager = Android.App.Application.Context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();

            SurfaceOrientation orientation = windowManager.DefaultDisplay.Rotation;
            bool isLandscape = orientation == SurfaceOrientation.Rotation90 ||
                orientation == SurfaceOrientation.Rotation270;
            return isLandscape ? DeviceOrientation.Landscape : DeviceOrientation.Portrait;
        }
    }
}
View Code

3、注册平台实现

在各个平台项目中实现此接口后,必须通过 DependencyService 注册平台实现,Xamarin.Forms 才可以在运行时找到它们。 通常使用 DependencyAttribute 完成此操作,它指示指定的类型提供接口实现。下面的示例演示如何使用 DependencyAttribute 注册 IDeviceOrientationService 接口的 iOS 实现:

using Xamarin.Forms;

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

在此示例中,DependencyAttribute 通过 DependencyService 注册 DeviceOrientationService(参数是 可提供所需接口的具体实现的类型。 同样,其他平台上的 IDeviceOrientationService 接口的实现也应通过 DependencyAttribute 注册。有关通过 DependencyService 注册平台实现的详细信息,请参阅 Xamarin.Forms DependencyService 注册和解析

4、解析平台实现

通过 DependencyService 注册平台实现后,必须先解析实现,才能调用它们。 通常使用 DependencyService.Get<T> 方法在共享代码中完成此操作。

下面的代码示例说明了如何调用 Get<T> 方法解析 IDeviceOrientationService 接口并调用 GetOrientation 方法:

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

有关通过 DependencyService 解析平台实现的详细信息,请参阅 Xamarin.Forms DependencyService 注册和解析

DependencyService 注册和解析

1、注册平台实现

必须通过 DependencyService 注册平台实现,Xamarin.Forms 在运行时才可以找到它们。

可以使用 DependencyAttribute 或 Register 方法执行注册

注:使用 NET 本机编译的 UWP 项目的版本生成应使用 Register 方法注册平台实现

通过特性注册在上面说明了,这里说明下Register方法注册:

下面的示例演示如何使用 Register 方法注册 IDeviceOrientationService 接口的 iOS 实现:

[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);
    }
}
View Code

在此示例中,Register 在 IDeviceOrientationService 接口上注册具体类型 DeviceOrientationService。 也可以使用 Register 方法的重载通过 DependencyService 注册平台实现:

DependencyService.Register<DeviceOrientationService>();

在此示例中,Register 方法使用 DependencyService 注册 DeviceOrientationService,这样就会在具体类型所实现的接口上注册它。

2、解析平台实现

必须先解析平台实现,然后才能调用它们。 通常使用 DependencyService.Get<T> 方法在共享代码中完成此操作。 不过也可以使用 DependencyService.Resolve<T> 方法完成它。

默认情况下,DependencyService 仅解析具有无参数构造函数的平台实现。 但是,依赖项解析方法可以注入到使用依赖项注入容器或工厂方法的 Xamarin.Forms 中,以解析平台实现。 这种方法可用于解析具有带有参数的构造函数的平台实现。 有关详细信息,请参阅 Xamarin.Forms 中的依赖项解析

使用Get<T>

默认情况下,Get<T> 方法创建接口 T 的平台实现实例并将其作为单一实例,但是,可以更改这种行为。 有关详细信息,请参阅管理解析对象的生存期

使用 Resolve<T> 方法解析

Resolve<T> 方法在运行时使用 DependencyResolver 类注入到 Xamarin.Forms 的依赖项解析方法检索接口 T 的平台实现。 若未将依赖项解析方法注入到 Xamarin.Forms,Resolve<T> 方法将回退到调用 Get<T> 方法,来检索平台实现。 有关将依赖项解析方法注入到 Xamarin.Forms 的详细信息,请参阅 Xamarin.Forms 中的依赖项解析

下面的代码示例说明了如何调用 Resolve<T> 方法解析 IDeviceOrientationService 接口并调用 GetOrientation 方法:

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

3、管理解析对象的生存期

DependencyService 类的默认行为是将平台实现解析为单一实例。 因此,平台实现将在应用程序的生存期期间持续存在。

此行为由 Get<T> 和 Resolve<T> 方法上的可选参数 DependencyFetchTarget 指定。 DependencyFetchTarget 枚举定义以下两个成员:

  • 将平台实现作为单一实例返回的 GlobalInstance
  • 返回新的平台实现实例的 NewInstance,然后由应用程序负责管理平台实现实例的生存期。

Get<T> 和 Resolve<T> 方法均将其可选参数设置为 DependencyFetchTarget.GlobalInstance,因此始终会将平台实现解析为单一实例。 通过将 DependencyFetchTarget.NewInstance 指定为 Get<T> 和 Resolve<T> 方法的参数,可以更改此行为,来创建新的平台实现实例:

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

在此示例中,DependencyService为ITextToSpeechService接口创建平台实现的新实例, 随后的任何解析ITextToSpeechService的调用也将创建新实例。。

始终创建新的平台实现实例的结果是由应用程序负责管理实例的生存期。 这意味着,如果订阅平台实现定义的事件,不再需要此平台实现时,应取消订阅此事件。 此外,这意味着,平台实现可能需要实现 IDisposable 并在 Dispose 方法中清除这些资源。该示例应用程序在其TextToSpeechService平台实现中演示了此方案。

如果应用程序不再使用实现 IDisposable 的平台实现,它应调用对象的 Dispose 实现。 完成此操作的方式之一是使用 using 语句:

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

在此示例中,在调用SpeakAsync方法之后,using语句自动处置平台实现对象,这导致调用对象的Dispose方法,该方法执行所需的清除。

从图片库中选选取照片

本文介绍如何创建一种应用程序,使用户可通过该应用程序从手机的图片库中选取照片。 由于 Xamarin.Forms 不包含此功能,因此有必要使用 DependencyService 来访问每个平台上的本机 API。

更多查看

 

posted @ 2019-11-17 10:43  peterYong  阅读(919)  评论(0编辑  收藏  举报