34

すべての ViewModel を SimpleIoc に保存するのは正しいですか? たとえば、MainPage、Photos、Directories (したがって、3 つの ViewModels -> MainVM、PhotosVM、DirectoriesVM) の 3 つのページがあります。各ページの DataContext を ViewModelLocator の View Model Property に設定するか、ViewModels を MainVM のプロパティとしてネストして、各ページの DataContext を Main.PhotosVMProperty、Main.DirectoriesVMProperty などにバインドする必要がありますか? 誰かが IOC のアイデアと目的を説明してくれませんか?

4

2 に答える 2

133

まず、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 コンストラクターに渡されます。

なぜ私はこのすべての仕事をするのでしょうか?

  1. クラスを簡単に単体テストできるようにする
  2. コードをインターフェース駆動型にします。これは、具象クラスではなくインターフェイスを参照していることを意味します
  3. コードを疎結合にします。これは、誰かがインターフェイスの実装を変更でき、そのインターフェイスを使用するクラスは気にせず、再コーディングする必要がないことを意味します。
  4. クラスの依存関係を自動的に解決します。
  5. MVVM Light では、デザイン モード ( ) でいつ実行されているかがわかります。ViewModelBase.IsInDesignModeStaticこれは、Visual Studio のビューに実際のデータが含まれるように、ビューモデル データを提供するデザインタイム サービスを作成できることを意味します。
于 2013-01-04T09:09:22.497 に答える