2012-12-12 8 views
7

インターネットで見たWPF MVVMアプリケーションの例VMは、外部ライブラリの「古い」イベントを使用するサービスレイヤとやりとりするレイヤ、 HTTPなどを使用してWeb。しかし、私はすべてのM、V、VM、サービス、および他の部品を自分で構築すればどうなりますか?サービス層とビューモデル層との間の相互作用を適切に構築するにはどうすればよいですか? ObservableCollection<OrderModel>をサービスに入れてビューのビューモデルからそのまま返すことはできますか?これは悪いアプローチと考えられ、より良い選択肢がありますか?WPF MVVMアプリケーションのサービスレイヤのObservableCollection

答えて

6

これはもちろん可能です。このようなことを行う主な理由は、複数のWPFアプリケーション間の重複を減らすことです。

ただし、サービスレイヤー/データレイヤーの実装によっては、データベース接続を使用する長時間実行型のサービスである場合があります。 ObservableCollectionsは、サービス層がアプリケーションによって行われた変更を自動的にデータストアに同期させるという観点から魅力的です。ただし、データ自体から生じる変更(つまり、データを作成/変更する他のプロセスへの応答)を伝える場合は、複雑になります。

サービス層は、もはや参照の唯一の所有者ではないため、実際にインスタンスを置き換えることはできません(大規模な変更の場合)。 UIがコレクションに持つすべてのバインディングを解除します。

したがって、1つのインスタンスを最新の状態に保つことに固執します。サービスがデータベースにバインドされている場合、サービス内で長時間実行される監視プロセスをコード化しない限り、ObservableCollectionを最新の状態に保つための唯一の簡単な方法は、データベース接続/コンテキスト(LinqからSqlまたはEFの場合)を開く - そうでなければ関連するオブジェクトなどは取り戻すことができません(すべてのオブジェクトを強制的に読み込まない限り - スケーラビリティではありません)。

あなたの接続を管理できる何らかの管理レイヤーを書くことは可能ですが、避けられないポーリングやSQL Serverの通知に加えて、コードがかなり複雑になる可能性があります。

しかし、それは本当に依存しています - その特定の問題は目を引くものですが、あなたはそのようなことは単に問題ではないアーキテクチャと環境を持っているかもしれません。

あなたがそれを試してみたいと思ったら、私のアドバイスをお読みください。私のために?私はそれについて考えてきました - そして、いくつかのドメインモデルにINotifyPropertyChangedを追加する以外に、アプリケーションには独自のVMがあるという考えに固執します。複数のアプリケーションが同じVMを共有するかもしれませんが、サービス層自体の内部にはありません。

サービスレイヤーは、データとビジネスロジックへのアクセスを、通常はワンショットで提供します。 VMパターンのクラスは、より長い寿命を持つように設計されています。長時間実行されるサービスレイヤーをコーディングしようとすると、非常に難しくなります。特に将来のすべてのアプリケーションで発生するすべての問題を解決してください。必然的に、単一のアプリケーションのみのサービスレイヤー内でコーディングサービスまたはVMタイプを終了させることになります。その場合は、そのアプリケーションのコードベースにも入っている可能性があります。

0

私はいくつかの理由でそれをしません。彼らはここに文書化されています:Common mistakes with an observable collection

著者は、サービス層でそれらを使用することを含めて、人々がそれらで作るいくつかの間違いを経験します。

+0

この記事では、「モデルで使用する」セクションでは、モデルでOCを使用するのは悪いと述べていますが、変換なしでモデルがそのままビューに与えられると、多くの例が見られます。推奨事項の1つは、「モデルがINotifyPropertyChangedを実装する場合はそれを使用し、それ以外の場合は変換する」。だから、モデルで観測可能なコレクションを使用することは、誰もが悪い習慣とはみなされません...とにかく、問題は、代替方法は何ですか? – Athari

+0

私は代わりの方法(正しい方法)はIEnumerableを使用することだと考えています。 @PeteHのように、できるだけ遠くに、つまりViewModelでOCを使用するようにしてください。また、OnCollectionChangedなどのサブスクリプションを持つViewModelsのObservableCollectionをプロパティとして公開するCollectionViewModelクラスを作成します。 – Heliac

2

ObservableCollectionは、 "observable"アスペクトが関連するポイント(通常はVMがVに何かを公開している)からのみ使用するようにしたいと思います。リストやコレクションのようなより一般的なものに固執するように誘惑されることがあります(特にそうでないものが特に必要な場合を除きます)。いずれにしても、古いIEnumerableに基づいてObservableCollectionを作成するには、VMが十分に簡単です。

特に、ObservableCollectionのSystem.Collections名前空間内の配置は、Microsoftが特別なクラス(と確かにwpf固有のものではない)とは考えていないように思われます。

+0

"従来の"リストや列挙型に固執する問題は、何かがあるときにviewmodelを介してビューを更新する必要があることですリストに追加されました。したがって、ビューモデルはサービスによって新しい項目について通知される必要があります。イベントを追加すると、それは観測可能なコレクションの悪い(おそらくバグのような)実装のように見えます。 – Athari

+0

@Athari私はあなたがどこから来ているかを見ることができます - あなた自身のObservableCollectionを実装することは間違いありません。スタックをさらに見下ろすと、サービスがどのように変化したのかを知ることができますか? – PeteH

+0

@Athari - それはまさに私がしていることです。 (DataGridの新しい行を使用せずにエンティティを追加する)新しい項目をプログラムで追加すると、リポジトリのCreateメソッドからスローするOnEntityAddedイベントが発生します。** OnEntityAdded(新しいModelEntityAddedEventArgs(エンティティ))** 。ご覧のように、エンティティはイベント引数で渡されます。私のサービス層はこのイベントを購読します。 – Heliac

関連する問題