MVVM and asynchronous data access
c#, caliburn.micro, mvvm, system.reactive, wpf
Solution
Dictionary<int, IObservable<IAsset>> inflightRequests;
public IObservable<IAsset> GetSomeAsset(int id)
{
// People who ask for an inflight request just get the
// existing one
lock(inflightRequests) {
if inflightRequests.ContainsKey(id) {
return inflightRequests[id];
}
}
// Create a new IObservable and put in the dictionary
lock(inflightRequests) { inflightRequests[id] = ret; }
// Actually do the request and "play it" onto the Subject.
var ret = new AsyncSubject<IAsset>();
GetSomeAssetForReals(id, result => {
ret.OnNext(id);
ret.OnCompleted();
// We're not inflight anymore, remove the item
lock(inflightRequests) { inflightRequests.Remove(id); }
})
return ret;
}
Problem
So I have a WPF application using the MVVM pattern (Caliburn.Micro). I got the views and view-models wired up and basicly what is missing is the data. The data is to be retrieved "on-demand" either from a WCF service, local storage or from memory/cache - reason being to allow for offline-mode and to avoid uneccessary server communication. Another requirement is that the data is retrieved asynchronously so the UI thread is not blocked. So I was thinking to create some kind of "AssetManager" that the viewmodels use to request data: ``` _someAssetManager.GetSomeSpecificAsset(assetId, OnGetSomeSpecificAssetCompleted) ``` Note that it is an asynchronous call. I run into a few different problems though. If the same asset is requested at (roughly) the same time by different view-models, how do we ensure that we don't do unecessary work and that they both get the same objects that we can bind against? Not sure I'm having the right approach. I've been glancing a bit at Reactive Framework - but I have no idea how to use it in this scenario. Any suggestions on framework/techniques/patterns that I can use? This seems to be a rather common scenario.