すべての ViewModel を SimpleIoc に保存するのは正しいですか? たとえば、MainPage、Photos、Directories (したがって、3 つの ViewModels -> MainVM、PhotosVM、DirectoriesVM) の 3 つのページがあります。各ページの DataContext を ViewModelLocator の View Model Property に設定するか、ViewModels を MainVM のプロパティとしてネストして、各ページの DataContext を Main.PhotosVMProperty、Main.DirectoriesVMProperty などにバインドする必要がありますか? 誰かが IOC のアイデアと目的を説明してくれませんか?
2 に答える
まず、ViewModelLocator の機能と、それを使用する理由を見てみましょう。
ViewModelLocator は App.xaml ページでオブジェクトとして宣言されており、アプリケーション シングルトンです。1 つだけを用意し、実行時にアプリケーションで使用できるのは 1 つだけです。
ViewModelLocator は、MVVM Light のすべての ViewModel のソースです。ViewModel ごとに、ViewModelLocator にプロパティがあり、View の ViewModel を取得できます。このコードは次のようになります。
public class ViewModelLocator
{
public MainPageViewModel MainPage
{
get { return new MainPageViewModel(); }
}
}
これは私の App.xaml の一部です:
<Application.Resources>
<vm:ViewModelLocator
x:Key="ViewModelLocator" />
</Application.Resources>
これは View.xaml の一部です
DataContext="{Binding MainPage, Source={StaticResource ViewModelLocator}}"
ここまでは順調ですね。最初の質問に答えるには、MVVM Light で Ioc を使用する必要がありますか? いいえ。ViewModelLocator によって完全に構築およびインスタンス化されたビューにビューモデルが提供されるため、その必要はありません。
さて、2 番目の質問ですが、IoC の目的は何ですか?
IoC は、次のことができるように設計されています。
Mvvm Light を使用すると、上記を次のように実行できます。
public class ViewModelLocator
{
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
SimpleIoc.Default.Register<MainViewModel>();
}
public MainViewModel Main
{
get { return SimpleIoc.Default.GetInstance<MainViewModel>(); }
}
}
public class MainViewModel
{
public ObservableCollection<Foo> Foos { get; set; }
public MainViewModel(IDataService dataService)
{
_dataService=dataService;
Foos=_dataService.GetFoos();
}
}
呼び出し時に MainViewModel を解決するとき
SimpleIoc.Default.GetInstance<MainViewModel>()
内部で行われるのは、SimpleIoc が、MainViewModel に依存関係 (コンストラクターのパラメーター) があるかどうかを確認することです。次に、登録されているインターフェイスを調べて、これらのパラメーターを解決しようとします。これは再帰的に行われるため、DataService に依存関係がある場合はインスタンス化され、同様にインスタンス化されているときに DataService コンストラクターに渡されます。
なぜ私はこのすべての仕事をするのでしょうか?
- クラスを簡単に単体テストできるようにする
- コードをインターフェース駆動型にします。これは、具象クラスではなくインターフェイスを参照していることを意味します
- コードを疎結合にします。これは、誰かがインターフェイスの実装を変更でき、そのインターフェイスを使用するクラスは気にせず、再コーディングする必要がないことを意味します。
- クラスの依存関係を自動的に解決します。
- MVVM Light では、デザイン モード ( ) でいつ実行されているかがわかります。
ViewModelBase.IsInDesignModeStatic
これは、Visual Studio のビューに実際のデータが含まれるように、ビューモデル データを提供するデザインタイム サービスを作成できることを意味します。