c# - RIAデータサービスの呼び出しをサービスレイヤーにリファクタリングするにはどうすればよいですか?

c# silverlight entity-framework mvvm ria

RIAサービスとエンティティを使用して、Silverlight 4アプリでいくつかの基本的なMVVM設計原則に取り組んでいます。正常に動作するように見える基本的なシナリオは次のとおりです。

DataViewModel.cs

public DataViewModel : NotificationObject

    private DataDomainContext _dataContext;

    public DataViewModel()  
    {
       _dataContext = new DataDomainContext();

       if (!DesignerProperties.IsInDesignTool)
       {
         Data = _dataContext.Data;
         dataContext.Load(_dataContext.GetDataQuery(), null, null);
       }
    }

    private IEnumerable<DataEntity> _data;
    public IEnumerable<DataEntity> Data   // INPC property
    {
        get { return _data; }
        set
        {
            if (value != _data)
            {
                _data = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Data"));
            }
        }
    }
}


私のビューのDataGridは、DataViewModel.Dataに一方向にバインドされています。DataDomainContextは、DataEntityオブジェクトのドメインサービスをコンパイルした後に公開されるRIAドメインコンテキストです。

DALからビューモデルを分離したいと思います。ドメインコンテキストにデータを要求する処理を行うDataServiceクラスが必要です。

public DataViewModel : NotificationObject

    private DataService _dataService;

    public DataViewModel(DataService dataService)  
    {
       _dataService = dataService;

       if (!DesignerProperties.IsInDesignTool)
       {
         Data = _dataService.Data;
         _dataService.GetData();
       }
    }

    ...
}


しかし、私はそれを正しくするようには思えません。これは簡単にできますか?以前にコールバックを使用したデータサービスを設計したことがありません。 INPCを介して3つのクラス間でDataプロパティをチェーン接続しようとしましたが、UIのDataGridが空白になります。また、新しいタイプのコレクションDataDtoに変換したいので、プレゼンテーションレイヤーがバックエンドに結合されていません。私は運がなければこのようなものを試しました:

DataService.cs

public DataService : INotifyPropertyChanged
{
   public DataService()
   {
     _dataContext = new DataDomainContext();
   }

   public event PropertyChangedEventHandler PropertyChanged;

   public void GetData()
   {
     DataEntities = _domainContext.Data;
     _dataContext.Load(_dataContext.GetDataQuery(), FinishedLoading, null);
   }

   private void FinishedLoading(...)
   {
      Data = DataEntities.Select(de => new DataDto(de));
   }

   public IEnumerable<DataDto> Data { ... }  // INPC property, used for binding in ViewModel

   public IEnumerable<DataEntity> DataEntities { ... }  // INPC property

   ...
}


私はここで正しい軌道に乗っていますか?高いレベルから何か不足していますか、それとも詳細が正しくありませんか?

編集:

私は最終的にこれを理解することができました。答えは、Action <>を介してコールバックをデータサービス/リポジトリの呼び出しに渡すことです。呼び出しの戻り値の型は実際には無効であり、イベント引数は結果を配信するために使用されます。誰かが興味を持っているなら、私はいくつかの実用的なコードを投稿してうれしいです、コメントにリクエストを残してください。
答え
あなたは正しい方向に進んでいると思いますが、実際には、ビューモデルをデータサービスから切り離そうとしている場合、ソリューションは正しくありません。現在、これとよく似たアプリを開発しています。人によってmvvmについての考え方は異なります。これは、(Visual Studioを使用して)試行錯誤から学んだ私の個人的なアプローチにすぎません。

まず、silverlightアプリプロジェクトを作成し、.webプロジェクトでホストします。
Silverlightプロジェクトは、ビューとビューモデルを保持します。ビューモデルには、データサービスではなく、モデルを含める必要があります。ただし、ビューモデルには、モデルを設定するためのデータサービスのインスタンスが必要です。データサービスはどこにありますか?私はあなたが尋ねたのはうれしいです:)。別のプロジェクト、WCF RIAサービスクラスライブラリを追加します。これは実際には2つのプロジェクト、riaサービス(サーバー側)のdllと対応するsilverlight(クライアント側)のdllです。エンティティフレームワークまたはその他のデータベースアクセスコードをサーバー側に追加できます。その後、サーバーサービスプロジェクトにドメインサービスを追加します。最初にそれをビルドし(重要)、次にクライアント側のriaサービスdllに移動し、次のようなデータサービスのメソッドを使用してデータサービスクラスを作成します。

public void GetData( string filter, Action<LoadOperation<MyEntityType>> callback )
    {
        var q = from e in _context.GetDataQuery()
                where e.SomeField.Contains(filter)
                select e;
        _context.Load(q, LoadBehavior.RefreshCurrent, callback, null);
    }


データサービスは変更されたInotifyプロパティを実装しないでください。これはビューモデルの役割です。
Silverlightプロジェクトでriaサービスクライアント側dllを参照し、Webホストプロジェクトでriaサービスサーバー側dllも参照します。
ビューモデルは次のようにこのデータサービスを呼び出す必要があります。

IEnumerable<MyEnityType> Model {get;set;}
//NOTE: add notify property changed in setter!

private void GetData()
{
    _myDataService.GetData( _filter, loadOperation =>
            {
                if ( loadOperation.HasError )
                    HandleError(loadOperation.Error);    
                Model = loadOperation.Entities;
            } );
}


それらを分離したい場合は、さらに一歩進んでデータサービスのインターフェイスを実装できます。このアプローチを採用すると、データサービスの再利用が可能になります(デスクトップアプリや電話アプリが必要な場合)。これで問題が解決することを願っています。
関連記事

c# - MoqでHttpApplicationStateをモックするときにオブジェクトを設定できないようです

c# - ラインオブジェクトのエンドキャップの幅または高さの値を取得するにはどうすればよいですか?

c# - データベースにアクセスしてエンティティフレームワークデータをテストする

c# - LoadAsyncとMemoryStreamを使用して、データベースから画像ボックスに画像をロードしたい

c# - リピーターをカスタムクラスの配列にバインドする方法[閉まっている]

c# - CSSをasp.net Webアプリケーションに追加する方法

c# - WP7-アニメーションが早すぎて効果が残っていない

c# - richTextbox1からtextbox1?

c# - WPF:IValueConverterからスローされたUIにエラーメッセージを表示する方法

c# - Farseer 3.3有効化されていないボディが有効化された場合に衝突するかどうかのチェック(スポーン)