私はこれについてすべて間違っているかもしれませんが、私は正しい道を進んでいると思いました. 私は初めて WPF アプリを作成していますが、まだいくつかの方法に慣れています。
私の考え
- 私の目標は、ViewModel クラスをよりテストしやすくすることです。
- ViewModel はサービス クラスに依存しており、サービス クラスがないと機能しません。
- したがって、サービスを ViewModel に挿入して、テスト目的でサービスのモックを開始できるようにすることは、私には理にかなっているように思えます。
私がしたこと
- 「UploaderViewModel」と呼ばれるビュー モデルへの XAML 参照を作成しました。
<Window.DataContext> <viewModels:UploaderViewModel> </viewModels:UploaderViewModel> </Window.DataContext>
注:注射を試みる前に、これはうまくいきます
- app.xaml.cs ファイルで構造マップを設定します。
void App_Startup(object sender, StartupEventArgs eventArgs) { ContainerBootstrapper.BootstrapStructureMap(); ProcessStartupArguments(eventArgs); }
私のブートストラッパークラスを呼び出します:
public static class ContainerBootstrapper
{
public static void BootstrapStructureMap()
{
ObjectFactory.Initialize(
x => x.For<IVEDocumentService>().Use<VEDocumentService>()
);
}
}
次に、UploaderViewModel クラスに IVEDocumentService をコンストラクタ パラメータとして使用させます。
public UploaderViewModel(IVEDocumentService documentService) { _documentService = documentService; //other unrelated code below this }
何がうまくいかないのか
ViewModel の既定のコンストラクターが見つからないという XAML エラーが表示されUploaderViewModel()
ますUploaderViewModel(IVEDocumentService documentService)
。
質問
- これを解決する最善の方法は何ですか?
- UploaderViewModel() コンストラクターを作成し、StructureMap にサービスのインスタンスを使用して UploaderViewModel を呼び出させる必要がありますか、それとももっと良い方法がありますか?
更新 1 -- リソース ディクショナリを使用しようとすると、StructureMap エラーが発生します。
this SO Answer to a similar questionに基づいて、私は試しました:
- UploaderViewModel のインスタンスをリソース ディクショナリに追加するように App_Startup を更新します。
void App_Startup(object sender, StartupEventArgs eventArgs) { ContainerBootstrapper.BootstrapStructureMap(); var uploaderViewModel = new UploaderViewModel(new Container().GetInstance<IVEDocumentService>()); Current.Resources["UploaderViewModel"] = uploaderViewModel; ProcessStartupArguments(eventArgs); }
- 宣言
DataContext="{StaticResource UploaderViewModel}"
に追加<Window>
<viewModels:UploaderViewModel/>
私の宣言をコメントアウトしました
これを行うと、StructureMap はエラーをスローするようになりました。
"StructureMap 例外コード: 202PluginFamily のデフォルト インスタンスが定義されていません