web-dev-qa-db-ja.com

MVVMデータアクセス層をどこに配置しますか?

WPFのMVVMデザインパターンを調査しています。しかし、データアクセスコードをどこに置くべきかわからないのですか?

私が見たいくつかの例では、データアクセスはViewModelで直接実行されます。 ViewModelにlinqto sqlのようなものを入れるのは奇妙に思えますか?他の例には、データアクセス用の別のプロジェクトがありますが、これはもっと似ているように見えますか?

これは一般的なアプローチですか?ここで何かが足りないような気がします!

ありがとう

28
Dan Black

別のレイヤーを追加します。基本的に必要なのはデータファクトリです。データベースにCRUDを実行し、クリーンなPOCOオブジェクトをViewModelに返すクラスのセットを作成する必要があります。

見るのに良い例は Nerd Dinner 本でしょう。 MVVMではなくMVCを対象としていますが、パターンは非常に似ており、そのソリューションでデータにアクセスする方法が出発点として適しています。

お役に立てれば。

12
Lukasz

LINQプロジェクトを使用してMVVMを整理する方法は次のとおりです。

モデル-モデルはシステムの状態だと思います。データへのインターフェースを提供し、システムステータスを追跡します。モデルはViewModelまたはViewを認識しません。データとさまざまなイベントへのパブリックインターフェイスを提供するだけで、状態が変更されたことをコンシューマー(通常はViewModels)に通知します。

ViewModel-ViewModelは、ビューに必要なすべてのデータの整理または構造化を担当し、ビューのステータス(データグリッドの現在選択されている行など)を追跡します。 )、およびビューでのアクション(ボタンの押下など)への応答。ビューが何を必要としているかは知っていますが、実際にはビューについては知りません。

ビュー-ビューは、UIの実際のルックアンドフィールです。これには、すべての組み込みおよびカスタムコントロール、それらの配置方法、およびスタイル設定方法が含まれています。 ViewModelについて知っていますが、そのプロパティにバインドするためだけです。

ゲートウェイ-これはあなたの質問に直接対処する部分です。ゲートウェイ(基本的に「DataAccessLayer」の言い方です)は、独自の独立したレイヤーです。これには、データソース(データベース、XMLファイルなど)との間でデータをCRUDまたは選択、挿入、更新、および削除するためのすべてのコード(LINQクエリを含む)が含まれています。また、モデルへのパブリックインターフェイスを提供し、モデルがデータソースの更新に必要な詳細(クエリなど)を気にすることなく、システム状態の維持に集中できるようにします。

DataAccessクラス-C#では、これらは要素データオブジェクトをモデル化する非常に単純なクラスです。 LINQクエリを使用して何かを選択する場合、通常はIEnumerable<T>またはList<T>を作成します。ここで、Tはデータオブジェクトの1つです。データオブジェクトの例は次のとおりです。

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

このようなデザインの大きな利点は、それがあなたの懸念を本当に分離することです。すべてに専門的な仕事があり、(通常は)どのようなことがどこに行くのかを知るのは非常に簡単です。

不利な点は、小さなプロジェクトではやり過ぎかもしれないということです。基本的に単一の願いを複数のレイヤーに渡すパブリックインターフェイス用の多くのインフラストラクチャを作成することになります。したがって、次のようなシナリオになる可能性があります。[ユーザーが[送信]をクリックし、ViewModelがModelにAddNewPersonを指示し、ModelがGatewayにInsertPersonを指示する]このようなシナリオではなく、[ユーザーが[Submit]をクリックし、ViewModelがデータベースに新しいレコードを直接追加する]。

お役に立てば幸いです。

42
devuxer

データアクセスはnotである必要があります。これは、ドメインモデルのビュー固有の(場合によっては簡略化された)表現であると想定されているためです。

ある種のマッパーを使用して、ビューモデル(MVVMではVM)をモデル(最初のM)にマップします。モデル内の新しいオブジェクトは、ファクトリパターンを使用して作成できます。作成したら、リポジトリパターンを使用してデータベースに保存できます。リポジトリはデータアクセスレイヤーを表します。リポジトリでは、NHibernateやEntityFrameworkなどのO/Rマッパーを使用できます。

編集:
GraemeFがデータアクセスコードをモデルに配置することを提案しているようです。これは[〜#〜] not [〜#〜]良いアプローチです。これにより、更新が必要になります。たとえばから移行する場合は、ドメインモデルSQLServerからOracleまたはXMLファイルへ。 ドメインオブジェクトは、それらがどのように永続化されるかを心配する必要はありません。リポジトリパターンは、ドメインをその永続性から分離します。

11
Kristoffer

MVVMはModelView、およびViewModelの略です。不足しているのはモデルです。これは、データアクセスコードが存在する場所です。

ViewModelはモデルを受け取り、それをビューに表示して表示するため、通常は次のようになります。

class PersonModel : IPerson
{
    // data access stuff goes in here
    public string Name { get; set; }
}

class PersonViewModel
{
    IPerson _person;

    public PersonViewModel(IPerson person)
    {
        _person = person;
    }

    public Name
    {
        get { return _person.Name; }
        set { _person.Name = value; }
    }
 }

PersonViewは、モデル自体に直接バインドするのではなく、PersonViewModelのプロパティにバインドします。多くの場合、MVVMについて何も知らない(そしてそうすべきではない)データアクセス層がすでにあるかもしれませんが、それでもViewModelを構築してビューに表示することができます。

7
GraemeF

WPFアプリケーションフレームワーク(WAF)には、Model-View-ViewModel(MVVM)パターンがどのように機能するかを示すサンプルアプリケーションが含まれていますエンティティフレームワークと組み合わせて使用​​できます。

2
jbe

ViewModelは、ビューにサービスを提供するだけの薄いレイヤーである必要があります。私の経験則:UIの表示に関係する場合は、ViewModelに属します。それ以外の場合は、モデルに含める必要があります。

1
Ryan Emerle