かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

ReactivePropertyで自動でUIスレッドにイベント発行を変えるのを抑止する その2

blog.okazuki.jp

上記記事では、ViewModelの中でSynchronizationContextSchedulerを作成していましたが、これだと単体テストが辛いということになります。これをいい感じにするには、ちょっと工夫がいるのですが…。例えばPrism.Unityを使うと以下のようにViewModelのコンストラクタの引数に渡すものを上書きすることができます。Unityの機能ですね。

具体的には、AppクラスでConfigureViewModelLocatorメソッドをoverrideして、ViewModelLocationProvider.SetDefaultViewModelFactoryの処理を置き換えることで対応可能です。

protected override void ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();
    ViewModelLocationProvider.SetDefaultViewModelFactory(x => 
        this.Container.Resolve(x, 
            new ParameterOverride("scheduler", new SynchronizationContextScheduler(SynchronizationContext.Current))));
}

こうしておくと、ViewModelでは、以下のような引数を定義しておくだけでUIスレッドに紐づいたSchedulerが設定されてきます。

public MainPageViewModel(IScheduler scheduler)
{
    this.Time = new ReactiveProperty<string>(scheduler);

こうしておくと、単体テストでISchedulerをTestSchedulerに差し替えたりということが簡単にできるようになります。