次の方法で共有


Xamarin.Forms の DependencyService の登録と解決

Xamarin.Forms の DependencyService を使用してネイティブ プラットフォームの機能を呼び出す場合、プラットフォームの実装を DependencyService に登録してから、共有コードから解決してそれらを呼び出す必要があります。

プラットフォームの実装の登録

プラットフォームの実装を DependencyService に登録して、実行時に Xamarin.Forms でそれらを検索できるようにする必要があります。

登録は、DependencyAttribute、または RegisterRegisterSingleton メソッドを使用して実行できます。

重要

.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()
        {
            ...
        }
    }
}

この例では、DependencyAttribute によって DeviceOrientationServiceDependencyService に登録しています。 その結果として、実装されるインターフェイスに対して具象型が登録されます。

同様に、DependencyAttribute を使用して他のプラットフォーム上の IDeviceOrientationService インターフェイスの実装を登録する必要があります。

Note

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 メソッドによって DeviceOrientationServiceDependencyService に登録しています。 その結果として、実装されるインターフェイスに対して具象型が登録されます。

または、RegisterSingleton メソッドを使用して、既存のオブジェクト インスタンスをシングルトンとして登録することもできます。

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

この例では、RegisterSingleton メソッドによって、DeviceOrientationService オブジェクト インスタンスが IDeviceOrientationService インターフェイスに対してシングルトンとして登録されます。

同様に、Register メソッド、または RegisterSingleton メソッドを使用して、他のプラットフォーム上の IDeviceOrientationService インターフェイスの実装を登録できます。

重要

Register および RegisterSingleton メソッドによる登録は、プラットフォームの実装によって提供される機能が共有コードから呼び出される前に、プラットフォーム プロジェクト内で実行される必要があります。

プラットフォームの実装の解決

プラットフォームの実装は、呼び出される前に解決される必要があります。 これは一般に、DependencyService.Get<T> メソッドを使用して共有コード内で実行されます。 ただし、これは DependencyService.Resolve<T> メソッドを使用して実現することもできます。

既定では、パラメーターなしのコンストラクターがあるプラットフォームの実装だけが、DependencyService によって解決されます。 ただし、依存関係挿入コンテナーまたはファクトリの方法を使用してプラットフォームの実装を解決する依存関係解決方法を、Xamarin.Forms に挿入することができます。 この方法を使用して、パラメーターがあるコンストラクターを持つプラットフォームの実装を解決できます。 詳細については、「Xamarin.Forms での依存関係の解決」を参照してください。

重要

DependencyService に登録されていないプラットフォームの実装を呼び出すと、NullReferenceException がスローされます。

Get<T> メソッドを使用した解決

Get<T> メソッドでは、実行時にインターフェイス T のプラットフォームの実装が取得され、次のいずれかが実行されます。

  • そのインスタンスがシングルトンとして作成されます。
  • 既存のインスタンスがシングルトンとして返されます。これは RegisterSingleton メソッドによって DependencyService に登録されたものです。

どちらの場合も、インスタンスはアプリケーションの有効期間にわたって存続し、同じプラットフォームの実装を解決する後続の呼び出しでは同じインスタンスが取得されます。

次のコードは、Get<T> メソッドを呼び出して IDeviceOrientationService インターフェイスを解決してから、その GetOrientation メソッドを呼び出す例を示しています。

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

または、このコードは、1 行に圧縮できます。

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

Note

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 メソッドを呼び出す例を示しています。

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

または、このコードは、1 行に圧縮できます。

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

Note

Resolve<T> メソッドで Get<T> メソッドの呼び出しにフォールバックする場合、既定では、インターフェイス T のプラットフォームの実装のインスタンスがシングルトンとして返されます。 ただし、この動作は変更可能です。 詳細については、「解決済みのオブジェクトの有効期間の管理」をご覧ください。

解決済みのオブジェクトの有効期間の管理

DependencyService クラスの既定の動作では、プラットフォームの実装がシングルトンとして解決されます。 そのため、プラットフォームの実装は、アプリケーションの有効期間にわたって存続します。

この動作は、Get<T> メソッドと Resolve<T> メソッドの省略可能な DependencyFetchTarget 引数によって指定されます。 DependencyFetchTarget 列挙体で 2 つのメンバーを定義します。

  • プラットフォームの実装をシングルトンとして返す GlobalInstance
  • プラットフォームの実装の新しいインスタンスを返す NewInstance。 アプリケーションは、プラットフォームの実装インスタンスの有効期間を管理する責任を負います。

Get<T> メソッドと Resolve<T> メソッドの両方で、省略可能な引数が DependencyFetchTarget.GlobalInstance に設定されるので、プラットフォームの実装は常にシングルトンとして解決されます。 DependencyFetchTarget.NewInstanceGet<T> メソッドと Resolve<T> メソッドへの引数として指定して、プラットフォームの実装の新しいインスタンスが作成されるように、この動作を変更できます。

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

この例では、DependencyService によって ITextToSpeechService インターフェイス用にプラットフォームの実装の新しいインスタンスが作成されます。 ITextToSpeechService を解決するための後続の呼び出しでも、新しいインスタンスが作成されます。

プラットフォームの実装の新しいインスタンスが常に作成される結果として、アプリケーションがインスタンスの有効期間を管理する責任を負うようになります。 これは、プラットフォームの実装内に定義されているイベントに登録する場合に、プラットフォームの実装が不要になったときにイベントから登録を解除する必要があることを意味します。 さらにこれは、プラットフォームの実装では IDisposable を実装し、Dispose メソッド内でそれらのリソースをクリーンアップすることが必要な場合があることを意味します。 サンプル アプリケーションでは、TextToSpeechService プラットフォームの実装におけるこのシナリオを示しています。

アプリケーションでは、IDisposable を実装するプラットフォームの実装を使い終わったら、オブジェクトの Dispose 実装を呼び出す必要があります。 これを行うための 1 つの方法は、using ステートメントを使用することです。

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

この例では、SpeakAsync メソッドが呼び出された後に、using ステートメントによってプラットフォームの実装オブジェクトが自動的に破棄されます。 その結果として、必要なクリーンアップを実行するオブジェクトの Dispose メソッドが呼び出されます。

オブジェクトの Dispose メソッドの呼び出しの詳細については、「IDisposable を実装するオブジェクトの使用」をご覧ください。