Reactive Extensions(Rx)の適切なユースケースに頭を悩ませようとしています。引き続き発生する例は、UIイベント(ドラッグアンドドロップ、描画)、およびRxがWebサービス呼び出しなどの非同期アプリケーション/操作に適しているという提案です。
私は、RESTサービス用の小さなクライアントAPIを作成する必要があるアプリケーションに取り組んでいます。4つのRESTエンドポイントを呼び出す必要があります。3つは参照データ(空港、航空会社、ステータス)を取得するためのもので、4つ目は特定の空港の飛行時間を提供するメインサービスです。
3つの参照データサービスを公開するクラスを作成しました。メソッドは次のようになります。
public Observable<IEnumerable<Airport>> GetAirports()
public Observable<IEnumerable<Airline>> GetAirlines()
public Observable<IEnumerable<Status>> GetStatuses()
public Observable<IEnumerable<Flights>> GetFlights(string airport)
GetFlightsメソッドでは、各フライトに、出発する空港とフライトを運用している航空会社の参照を保持する必要があります。そのためには、GetAirportsとGetAirlinesからのデータを利用できるようにする必要があります。各空港、航空会社、ステータスは辞書(つまり辞書)に追加されるので、各フライトを解析するときに参照を簡単に設定できます。
flight.Airport = _airports[flightNode.Attribute("airport").Value]
flight.Airline = _airlines[flightNode.Attribute("airline").Value]
flight.Status = _statuses[flightNode.Attribute("status").Value]
私の現在の実装は次のようになります。
public IObservable<IEnumerable<Flight>> GetFlightsFrom(Airport fromAirport)
{
var airports = new AirportNamesService().GetAirports();
var airlines = new AirlineNamesService().GetAirlines();
var statuses = new StatusService().GetStautses();
var referenceData = airports
.ForkJoin(airlines, (allAirports, allAirlines) =>
{
Airports.AddRange(allAirports);
Airlines.AddRange(allAirlines);
return new Unit();
})
.ForkJoin(statuses, (nothing, allStatuses) =>
{
Statuses.AddRange(allStatuses);
return new Unit();
});
string url = string.Format(_serviceUrl, 1, 7, fromAirport.Code);
var flights = from data in referenceData
from flight in GetFlightsFrom(url)
select flight;
return flights;
}
private IObservable<IEnumerable<Flight>> GetFlightsFrom(string url)
{
return WebRequestFactory.GetData(new Uri(url), ParseFlightsXml);
}
現在の実装はSergeyの回答に基づいており、ForkJoinを使用してシーケンシャル実行を保証し、Flightsの前に参照データがロードされるようにします。この実装は、以前の実装のように「ReferenceDataLoaded」イベントを発生させるよりもはるかに洗練されています。