13

私は現在、MVVMを使用するための最初の実際の取り組みとなるものに取り組んでおり、MVVMを実装するための最良の方法に関するさまざまな記事を読んでいます。

私の現在の考えは、データモデルをデータ転送オブジェクトとして効果的に使用し、シリアル化可能にして、クライアント側とサーバー側の両方に存在させることです。両方のオブジェクトタイプが実際にはプロパティゲッターとセッターの単なるコレクションであり、その間の別のレイヤーが完全にやり過ぎのように見えることを考えると、論理的なステップのように思えます。

明らかに、通信するViewModelがないため、サーバー側でINotifyPropertyChangedが正しく機能しないという問題がありますが、サービスレイヤーのデータモデルから適切なドメインモデルオブジェクトを構築し、サーバー側のデータモデル大きな問題ではないと思います。

私はこのアプローチについてあまり多くの情報を読んでいないので、これがかなり標準的なものであるかどうかを知りたいのですが、これは多層環境でMVVMを実行する事実上の方法であると想定されていますか?私が物事について完全に間違った考えを持っているなら、他のアプローチについての考えもありがたいです。

4

3 に答える 3

6

快適に感じるモデルなら何でも使用できます。はい、すべてのプロパティにINotifyPropertyChanged動作が必要です。これがサービスレイヤーにどのように影響するかは、完全に実装に依存します。

私はあなたがあなたの見解であなたのDTOにバインドすることをあなたがメンションしていると思いますか?

アプリケーションのレイヤー間にインピーダンスの不一致があることがわかります。つまり、ドメインモデルはおそらくリレーショナルモデルと似ていますが、微妙ではありますが重大な違いがあります。ドメインモデルとDTOの間にも不一致があります(オブジェクトがフラット化されたり、プロパティが計算されたりする可能性があります...)。DTOはおそらく特定の操作に必要なものを持つように設計されているため、DTOに直接バインドするのは魅力的ですが、DTOと、指定された結果を達成するためにビューに必要なものとの間にインピーダンスの不一致もあります。これがビューモデルの出番です。ビューモデルは、DTOプロパティをビューにプロキシする役割を果たし、検証エラーがあるかどうかをビューに通知し、コマンドを適切なハンドラー(保存、削除など)にルーティングします。 、.。

私は次のように設定する傾向があります:

// POCO object. Serializable.
public class AddressDto 
{    
   public int Id { get; set; }
   public string Street { get; set; }    
   public string City { get; set; }    
   public string Country { get; set; } 
}

// IDataErrorInfo for validation.
public class AddressViewModel : INotifyPropertyChanged, IDataErrorInfo
{
   private readonly AddressDto addressDto;

   public AddressViewModel(AddressDto addressDto)
   {
      this.addressDto = addressDto;      
   }

   public int Id { /* get and set for property changed event and update dto */ }
   public string Street { /* get and set for property changed event and update dto  */ }
   public string City { /* get and set for property changed event and update dto  */ }
   public string Country { /* get and set for property changed event and update dto  */ }
   ...

   // IDataErrorInfo implementation
}

public class EditAddressViewModel : INotifyPropertyChanged
{
   public AddressViewModel Address { /* get and set for property changed event */ }
   public ICommand Save { /* setup command */ }
   public ICommand Cancel { /* setup command */ }

   private void Save()
   {
   }

   private void Cancel()
   {
   }
}

EditAddressViewは、EditAddressViewModelにバインドされます。基本的に、ルールはすべてのUIの動作をビューモデルの観点から表現する必要があるということです。

はい、それは余分な作業を意味しますが、少し単純化するためにできることがあります(コード生成など)。私は実際に、流暢なAPIを使用してMVVMプロセス全体を簡素化することを目的としたライブラリに取り組んでいます。http://fluentviewmodel.codeplex.com/でチェックしてください

于 2010-04-28T09:23:02.570 に答える
3

私はこれについての専門家ではありません。私も同じシナリオでした。私はあなたに同意します、それはかなりやり過ぎです。私はかなり長い間このソリューションを使用してきましたが、問題は発生していません。サーバー側ではPropertyChangedイベントをサブスクライブしないため、INotifyPropertyChangedは私にとって大きな問題ではありません。データモデルで継承を使用する場合は、すべてをシリアル化できる必要があります。私のシナリオでは、データモデルに2つの基本クラスがあります。1つはデータ転送に使用され、もう1つは使用されません。

于 2010-04-27T13:32:09.300 に答える
2

ViewModelにプロパティ「Model」を設定することにしました。モデル自体には、すでにIPropertyNotifyChangedとIDataErrorInfoを実装しています。したがって、私のViewModelでは、コードがモデルに単に「フォールスルー」するプロパティをスキップします。代わりに、ビューはこれらのプロパティのモデルに直接バインドします。

ビューに合うようにモデルのデータを調整する必要がある、より複雑なケースでは、ViewModelでこれを行います。また、コマンドなどはViewModelにあります。しかし、ViewModelにボイラープレートコードがあり、モデルにすでにあるものと同じものを繰り返す理由はわかりません。

于 2010-04-28T09:49:58.747 に答える