読者です 読者をやめる 読者になる 読者になる

かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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に差し替えたりということが簡単にできるようになります。