Prism.Formsは、基本的にUnity(DIコンテナのほう)を使ってます。 こいつを使うとインスタンスの組み立てとかをお任せ出来るので楽ちんなのです!
Prism.Formsでは、そんなUnityの機能を拡張して、DependencyServiceから取得するインスタンスを自動でインジェクションしてくれる機能を提供しています。
従来
普通はDependencyServiceを使うときは以下のような手順になります。
インターフェースの作成
まず、PCLの所にインターフェースを定義します。ここではプラットフォームの名前を返すインターフェースみたいなのを作りました。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PrismUnityApp20.Models { publicinterface IPlatformNameProvider { string GetName(); } }
各プラットフォームでの実装の作成
そして、次に各プラットフォームで実装を行います。 例えばAndroidだと以下のような感じですね。Dependency属性つけてるのがポイント。
using PrismUnityApp20.Models; using Xamarin.Forms; [assembly: Dependency(typeof(PrismUnityApp20.Droid.Models.AndroidPlatformNameProvider))] namespace PrismUnityApp20.Droid.Models { publicclass AndroidPlatformNameProvider : IPlatformNameProvider { publicstring GetName() => "Android"; } }
UWPだと以下のような感じ。
using PrismUnityApp20.Models; using Xamarin.Forms; [assembly: Dependency(typeof(PrismUnityApp20.UWP.Models.UWPPlatformNameProvider))] namespace PrismUnityApp20.UWP.Models { publicclass UWPPlatformNameProvider : IPlatformNameProvider { publicstring GetName() => "UWP"; } }
PCLでインスタンスを取得する
DependencyServiceのGetメソッドを使ってインスタンスを取得します。
var x = DependencyService.Get<IPlatformNameProvider>();
var name = x.GetName(); // メソッドを呼ぶと各プラットフォームの実装が呼ばれる
Prism.Formsの場合
最後のDependencyServiceのGetメソッドを呼ばなくてもよくなります。具体的には、使いたいクラスのコンストラクタの引数でインターフェースを受け取るようにするだけで自動的に各プラットフォーム固有の実装がインジェクションされます。
private IPlatformNameProvider PlatformNameProvider { get; } public MainPageViewModel(INavigationService navigationService, IPlatformNameProvider pnp) { // インスタンスをとっておいてよしなに使うthis.PlatformNameProvider = pnp; }
こうすることのメリットは、なんといってもユニットテストが簡単になるという点ですね! テスト時には、Mock実装を簡単に差し込めるようになります。すばらし。
あと、個人的にGetメソッドかっこわるいと思ってたので、この機能は歓迎です。