GriffinHeart
GriffinHeart

Reputation: 450

RIA services async calls chaining on silverlight

So i'm trying to warp my head around MVVM and RIA services. But i'm quickly realizing its not like they sell it.

I can make things happen but everything seems ugly. For example i have a view model that needs a set of data to be loaded from multiple tables and etc.

My current aproach, chain async operations. This smells really bad:

_Model.GetSomethingById(Id, result =>
            {
                _saveIt = result;
                _Model.GetSomethingElse(result2 =>
                    {
                        _saveit2 = result2;
                        //now i have all the data, can finally work on it.
                        //Initialize Grids, tables, input etc...
                    });
            });

Is this the intended way to work with RIA? I'm missing something.

Sure i can include everything in the query at the service side, that is if everythings related. But that also smells bad.

Upvotes: 1

Views: 1530

Answers (4)

Myles J
Myles J

Reputation: 2880

You can make your code much cleaner by using coroutines. Compare the code below to the chaining example you included in your question.

public IEnumerable<IAction> Activate()
{
    var action = build.Query(service => service.Authenticate(login, password));
    yield return action;

    if (!action.Result.Success)
        yield break;

    var user = action.Result.User;

    action = build.Query(service => service.GetIssues(user));
    yield return action;

    foreach (Issue each in action.Result)
    {
        Issues.Add(each);
    }
}

Have a read of this: http://www.codeproject.com/KB/silverlight/FixingAllAsync.aspx

Upvotes: 0

Kyle McClellan
Kyle McClellan

Reputation: 2029

I really love the Async support Visual Studio is adding. The bits are early, but the syntax is much better. It looks something like this.

await TaskEx.WhenAll(
    this._context.Load(this._context.GetRedEntitiesQuery()).AsTask(),
    this._context.Load(this._context.GetGreenEntitiesQuery()).AsTask(),
    this._context.Load(this._context.GetBlueEntitiesQuery()).AsTask()
    );
// Now do stuff

I have a post about it here.

There are some known compatibility issues with the first CTP and I don't know whether they've updated it yet. It's worth checking into, though.

Upvotes: 2

Steve Wranovsky
Steve Wranovsky

Reputation: 5713

This is basically how your code should work with MVVM & RIA Services. I would have a few more tips, however:

  • Usually the initialization of Grids, etc., after you've retrieved data is not triggered from your ViewModel. Instead, its usually done through Binding with your XAML. Ie, if you have a single Entity object in your ViewModel that you're binding to, it would be preferable to have a default instance, and then copy the contents of the entity from result to _saveIt in your example. This would cause your binding in your XAML controls to just automatically be updated.

  • Its common in ria services to have a BusyIndicator control that's bound to a bool property in your ViewModel while you're waiting for data from the server. This can help with the appearance of the GUI while you're waiting for data from the server after initialization.

  • If you're doing any kind of DataTables, I would highly recommend RIA Services 1.0 SP1, this has some built in DomainCollectionView and DomainCollectionViewLoader classes for handling paging, binding, etc. I went around in circles for awhile trying to implement this on my own based on some early forum posts until I discovered it was included in SP1.

In general you're on the right track. There's just a lot of asynchronous code with RIA Services that is handled nicely when you do Binding from your XAML.

Upvotes: 3

alf
alf

Reputation: 18530

There's nothing wrong about it. If you prefer, you can create separate event handlers to make the code prettier. Also make sure to check for errors on each response.

Upvotes: 0

Related Questions