共用方式為


Xamarin.Forms DependencyService 註冊和解析

使用 Xamarin.FormsDependencyService 來叫用原生平臺功能時,平臺實作必須向 DependencyService註冊,然後從共用程式碼解析以叫用它們。

登錄平台實作

平台實作必須向 DependencyService 註冊, Xamarin.Forms 才能在運行時間找到它們。

您可以使用 或 RegisterRegisterSingleton 方法來執行DependencyAttribute註冊。

重要

使用 .NET 原生編譯的 UWP 專案發行組建,應該使用 Register 方法登錄平台實作。

透過屬性登錄

DependencyAttribute 可用於向 DependencyService 登錄平台實作。 該屬性表示所指定型別會提供介面的具體實作。

下列範例會使用 DependencyAttribute 來註冊 介面的 IDeviceOrientationService iOS 實作:

using Xamarin.Forms;

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

在此範例中,DependencyAttributeDependencyService 登錄 DeviceOrientationService。 這會導致具象型別向它所實作的介面登錄。

同樣地,其他平台上的 IDeviceOrientationService 介面實作應該向 DependencyAttribute 登錄。

注意

DependencyAttribute 登錄是在命名空間層級執行。

透過方法登錄

DependencyService.Register方法和 RegisterSingleton 方法可用來向 DependencyService註冊平台實作。

下列範例會 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);
    }
}

在此範例中,Register 方法向 IDeviceOrientationService 介面登錄 DeviceOrientationService 具象型別。 或者,Register 方法的多載也可用於向 DependencyService 登錄平台實作:

DependencyService.Register<DeviceOrientationService>();

在此範例中,Register 方法向 DependencyService 登錄 DeviceOrientationService。 這會導致具象型別向它所實作的介面登錄。

或者,現有的物件實例可以使用 方法註冊為單 RegisterSingleton 一實例:

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

在此範例中 RegisterSingleton ,方法會將 對象實例註冊 DeviceOrientationServiceIDeviceOrientationService 單一實例。

同樣地,其他平臺上介面的 IDeviceOrientationService 實作也可以向 Register 方法或 RegisterSingleton 方法註冊。

重要

使用 RegisterRegisterSingleton 方法註冊必須在平臺項目中執行,才能從共用程式代碼叫用平臺實作所提供的功能。

解析平台實作

必須先解析平台實作,才能叫用它。 這通常在共用程式碼中使用 DependencyService.Get<T> 方法來執行。 不過,也可以使用 DependencyService.Resolve<T> 方法來完成。

根據預設,DependencyService 僅會解析具有無參數建構函式的平台實作。 不過,您可以插入 Xamarin.Forms 相依性解析方法,以使用相依性插入容器或處理站方法來解析平台實作。 這種方法可用來解析具有參數建構函式的平台實作。 如需詳細資訊,請參閱 中的 Xamarin.Forms相依性解析。

重要

叫用尚未向 DependencyService 登錄的平台實作會導致擲回 NullReferenceException

使用 Get<T> 方法來解析

方法 Get<T> 會在運行時間擷取介面 T 的平台實作,並擷取下列其中一項:

  • 建立實例做為單一實例。
  • 傳回現有實例做為單一實例,這個實例是由 方法向 DependencyServiceRegisterSingleton 註冊。

在這兩種情況下,實例都會存留應用程式存留期,而解析相同平台實作的任何後續呼叫都會擷取相同的實例。

下列程式碼範例顯示呼叫 Get<T> 方法來解析 IDeviceOrientationService 介面,然後叫用其 GetOrientation 方法:

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

或者,此程式碼也可以壓縮成單一行:

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

注意

方法 Get<T> 預設會以單一方式傳回介面 T 平台實作的實例。 然而,可以變更此行為。 如需詳細資訊,請參閱管理已解析物件的存留期

使用 Resolve<T> 方法來解析

方法Resolve<T>會使用已插入 類別的相依性解析方法Xamarin.FormsDependencyResolver,在運行時間擷取介面T的平台實作。 如果尚未將相依性解析方法插入 Xamarin.Forms,此方法 Resolve<T> 會回復為呼叫 Get<T> 方法以擷取平台實作。 如需將相依性解析方法插入 至 Xamarin.Forms的詳細資訊,請參閱 中的 Xamarin.Forms相依性解析。

下列程式碼範例顯示呼叫 Resolve<T> 方法來解析 IDeviceOrientationService 介面,然後叫用其 GetOrientation 方法:

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

或者,此程式碼也可以壓縮成單一行:

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

注意

Resolve<T>當方法回復為呼叫 Get<T> 方法時,預設會以單一方式傳回介面T平台實作的實例。 然而,可以變更此行為。 如需詳細資訊,請參閱管理已解析物件的存留期

管理已解析物件的存留期

DependencyService 類別的預設行為是要將平台實作解析為 Singleton。 因此,平台實作會在應用程式存留期內存留。

此行為是以 Get<T> 上的 DependencyFetchTarget 選用引數和 Resolve<T> 來指定。 DependencyFetchTarget 列舉定義兩個成員:

  • GlobalInstance,此成員會將平台實作以 Singleton 傳回。
  • NewInstance,此成員會傳回平台實作的新執行個體。 平台執行個體的存留期接著會由應用程式負責管理。

Get<T>Resolve<T> 方法都將其選擇性引數設定為 DependencyFetchTarget.GlobalInstance,因此平台實作一律會解析為 Singleton。 若要變更此行為,可將 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 方法被叫用,它會執行所需的清理。

如需呼叫物件 Dispose 方法的詳細資訊,請參閱使用實作 IDisposable 的物件