1

私たちの新しいプロジェクトは、ViewModelLocator を使用してビューをビューモデルと結合する View first パターンから始まりました。

ViewModelファーストパターンに変更したいです。

これが私のビューモデルコンストラクターです:

public DeviceSelectionViewModel(IDataModel dataModel, IMessenger messenger)
{
    if (dataModel == null) throw new ArgumentNullException("dataModel");
    if (messenger == null) throw new ArgumentNullException("messenger");

    Selector = new PlantDataTemplateSelector();
    PlantSelector = new PlantNodesSelector();
    Plants = new List<Plant>(0);

    messenger = messenger;
    messenger.Register<PlantDataLoadedMessage>(this, m => DispatcherHelper.CheckBeginInvokeOnUI(() => OnPlantDataLoaded(m.Plants)));

    RefreshData(_dataModel);
}

最初に ViewModel を使用して適切な ViewModel を選択する方法を次に示します。

public class MainViewModel : Module
{

    public MainViewModel()
    {
        SelectedView = new DeviceSelectionViewModel();
    }

    public ViewModelBase SelectedView { get; set; }

}

View first では、コードを介して ViewModel を直接呼び出すことはなかったので、Constructor Dependency Injection は正常に機能しました。

コントローラー ViewModel を介して ViewModel を呼び出しているので、ViewModel コンストラクターの 2 つのパラメーターが必要です。

コントローラービューモデルで参照を保持し、コンストラクターに渡すのは適切ですか? このシナリオで DI がどのように機能するかについて、ここで何かが欠けていますか?

私はまだDI(Ninject)とMVVMでピースをまとめているので、親切にしてください:)

4

1 に答える 1

1

同じ問題がありました。

次の選択肢があります。

  • MainViewModelDeviceViewModel必要なパラメータの値を提供して作成します
  • MainViewModelすでに解決されているDeviceViewModel

DeviceViewModel最初のバリアントは、ビュー バインディングに対してのみ公開されている場合にカップリングを増加させます。MainViewModelと通信する場合、2 番目のオプションが必然的に必要になるインターフェイスを介して認識しDeviceViewModelない限り、カップリングは既に暗示されています。MainViewModelDeviceViewModel

最初のアプローチのもう 1 つの問題は、場合によっては、ネストされた VM の作成に、親 VM が必要なため、より多くの値が必要になることです。
これは、親 VM コンストラクターを拡張してこれらの追加パラメーターを含めることで解決できます。しかし、複雑な VM グラフを作成すると (実際には決してありませんが)、ルート VM のコンストラクターが肥大化する可能性があります。

現在、両方のオプションが混在しています。

すべての ViewModel はViewModelBase抽象クラスから継承します。いくつかのオーバーロードされたコンストラクターがあり、それらのほとんどはIViewModelFactory入力として取得されます。そのため、工場に必要なものを作成するよう依頼できますViewModel。Wee は、返される型については気にせず、作成された ViewModel の型のみをカプセル化して返すことにしました。したがって、それは真の DI ではありません。

Messanger も使用しますが、ViewModel は明示的にメッセージを送信できず、メッセージをサブスクライブすることしかできません。特定の VM が送信できる (さらにはサブスクライブできる) メッセージのセットを制限する方法として、意図的にこれを行いました。

于 2013-01-17T23:17:31.860 に答える