RIA Services, Silverlight and MVVM

Silverlight Logo

I've finally had a chance to take a look at the July CTP of RIA Services. My opinion is mixed, but its still pretty early. I ran through the simple walkthrough and it was easy to set up but it still felt as if there is too much Visual Studio magic (a complaint I've had for a long time now).

A Brief Overview

For the uninitiated let me explain a couple of things (though, please don't assume this blog entry is an introduction to RIA Services):

RIA Services is trying to share logic with the Silverlight client. That's the big story (IMHO). Some of this logic is a surface to query, validation attributes and outright code in other cases. Its trying to solve a difficult problem, but they've made a fundamental mistake in my book: RIA Services requires that all pieces are in a single solution file. But why? The magic is code generation.  

RIA Services starts with a Domain class which normally uses a model (Entity Framework or others) to expose the data.  As you change the domain class and the entities, RIA Services builds a code generated file in the Silverlight project (or other client files) for you:

The RIA Magic

As the GameDomain file and the GameModel's entities are changed, the generated code is regenerated to keep up with the changes.

Why This is Troubling

This makes sense in one case because as the domain and entities are changed, the code magically stays updated.  Which is a better experience than updating a Service Reference.  But it requires something called a RIA Link.  This link is between a client-side component (typically a Silverlight application) and a server-side component (typically an ASP.NET Web Site/Project).

The cost of this approach is that the projects must exist in the same solution file. This works for demo's and small projects, but in the big world of enterprise or Internet development this breaks down. Throw in composition strategies (like Prism solves) and it complicates it quite a lot.  I certainly hope that when it reaches 1.0 they'll have a solution for this. The current solution for this is to wrap the domain service with an ADO.NET Data Service, but that means there are two layers to go through instead of one and if that's the approach, just use ADO.NET Data Service instead, right?

Another Concern

While reading the well-written and lengthy overview on RIA Services (that comes with the RIA Services CTP) I noticed that RIA Services comes with a data source object (called DomainDataSource) that can be used directly within XAML to communicate with the domain class:

RIA Services Data Source

If you've been reading this blog for any length of time, you'll know that I think that data source objects are almost always evil in that they suggest that its ok to include data access in the user interface.  And the depth of interaction with the data source is really troubling here.

So What About RIA Services in MVVM?

My first thought was how this impact the best-practices of not co-minging UI and data.  I thought it might not work at all, but as often happens in these cases, the example isn't the exemplar that I can suggest.  The framework (aside from my concern about the solution file) actually allows this pretty easily.

So I went back and grabbed my MVVM example from my MSDN article (seen here: http://msdn.microsoft.com/en-us/magazine/dd458800.aspx) and refactored it to use RIA Services. The breakdown of that architecture was pretty simple:

MVVM Architecture

Notice I am using a RIA Domain Service on the server to expose the data model (instead of ADO.NET Data Services). This is broken up in the solution as a set of client-side projects and server-side projects:

RIA Services Project Breakdown

Notice that while in the typcial scenario (and walkthrough's) the RIA Link is betwen the Silverlight application and the web project, RIA Services allows you to have that link between separated parts of the solution. In this case, we have a MVVM.Data library that contains the entity model and the domain service class.  This allows us to re-use this in separate web projects (which is something that is harder to do in ADO.NET Data Services). We also have a MVVM.Client.Data Silverlight library that contains the model for the Silverlight application (and separates the access to the services so the client does not need to change).

The refactoring was fairly painless in that the entity types that were created with the generated code were identical to the data contract classes created by the ADO.NET Data Services - Service Reference class. I had to change the namespaces but the rest was identical.

In the model class I had to change how I was performing the queries, but the major change there was using the extension method syntax for the query instead of the LINQ syntax. The separation of the Model meant that the refactoring was simple (as the whole pattern is supposed to do).

public void GetGamesByGenre(string genre)
{
  // Get all the games ordered by release date
  var qry = Context.GetGamesQuery()
    .Where(g => g.Genre.ToLower() == genre.ToLower())     
    .OrderByDescending(g => g.ReleaseDate)
    .Take(MAX_RESULTS);

  ExecuteGameQuery(qry);
}

I do wish that the RIA Services style wasn't so RPC (Remote Procedure Call) but that may be because I see the value in client-side LINQ queries instead of "GetGamesQuery()" and such. I think the syntax could be a lot simpler.

Overall, I think that RIA Services can help solve some problems but the bottom line is still too much Visual Studio magic for my taste and the validation is still only covering the very simple cases. Rich validation is always going to be hard (read Rocky Lhotka's book if you don't believe me).

If you want to play with it, you can grab the code here:

http://wildermuth.com/downloads/MVVMExample_RIA.zip

What do you think?

Comments:

Gravatar

Various datasources in asp.net (sqldatasource,...) looked good at first, with few mouse clicks you could have working page, but that's not much different from old school mixing of SQL and VB code in spaghetti .asp files, imho. From RAD perspective and for small projects, it's probably fine, but with enterprise projects in mind where data is coming from all directions, this could be problem. Too much magic happening there, smells like work of architectural astronauts;) But time will show, too early to tell. Maybe.

Gravatar

My recommendation has been to make adding a domain service the same way we'd add a webservice or wcf service.

Rather than the magic code gen, you'd create a reference to a project that has domain services and from there it would generate the proxies and show up in the client app in the same manner a wcf service reference would show up.

I sent my idea to Brad to see what he thinks. To me, this would eliminate the 'magic' as well as to provide a more common way to add a service that developers are more accustom to at this point.

Gravatar

@Shawn: Would you mind if I took your MVVMExample_RIA and made some additional changed to it on my blog? My reply to this entry is too long for just a comment (for on, I think you are vastly overstating the solution problem, and I also want to make some improvements to better show off what RIA Services can do. (No, that doesn't mean I want to add the DomainDataSource. I agree, it is evil although I usually try to tone down that opinion.)

Gravatar

I've been looking at ways to create a robust architecture for Silverlight LOB solutions. I've looked at Prism, basic WCF and now RIA Services.

I share your concerns re the VS "magic" and sometimes wonder if all the effort that goes into making it easy to create simple POCS that "work" were refocused into providing a clear, intelligible platform (with a transparent roadmap) for creating serious solutions we might all be better off.

These complex code generation wizards are fine 1st time through. But try working with them in a typically iterative development cycle with many, many changes.

My other concern with this is the customers who will tend to assume they can create new Silverlight clients to run with EXISTING services and backends. Maybe the guy already has a secure, well tested WCF layer using the WS protocols which aren't supported - and you the one telling him - sorry bud it won't work with Silverlight???

Gravatar

I've been looking at ways to create a robust architecture for Silverlight LOB solutions. I've looked at Prism, basic WCF and now RIA Services.

I share your concerns re the VS "magic" and sometimes wonder if all the effort that goes into making it easy to create simple POCS that "work" were refocused into providing a clear, intelligible platform (with a transparent roadmap) for creating serious solutions we might all be better off.

These complex code generation wizards are fine 1st time through. But try working with them in a typically iterative development cycle with many, many changes.

My other concern with this is the customers who will tend to assume they can create new Silverlight clients to run with EXISTING services and backends. Maybe the guy already has a secure, well tested WCF layer using the WS protocols which aren't supported - and you the one telling him - sorry bud it won't work with Silverlight???

Gravatar

While I think RIA services are a good tool for the masses, I personally prefer the flexibility and feature set one gets with CSLA for Silverlight.
The solution setup is a bit more manual, but the nice thing is there is no "magic" - WYSIWYG.

I've been using CSLA with a MVVM approach is a lot of success, so there's not really an incentive to move to RIA.

Gravatar

I'm just starting to look at RIA Services. I've been working in Silverlight almost exclusively since version 2.0's release and follow the MVVM architecture for my apps.

I appreciate your incite into RIA Services and will dig deeper into it to see if its worth anything.

Gravatar

Hi Mr. Wildermuth,
I enjoyed a lot your articles! I'm evaluating MVVM pattern, learning with yours and Mr. Nikhil articles and thought about the following: If we create every views in our applications as a Control (not UserControl), with ViewStates and TemplateParts wouldn't be a perfect applicaton of MVVM? where the DefaultStyle would be a View and control logic the ViewModel?

Thanks,

Vítor

Gravatar

Hi Shawn,
Interesting article, I agree with your observations. I would like to try your code, but it seems to be using Silverlight 2, any chance of an upgrade to 3?
Thanks, Peter

Gravatar

Spot on. I cringe at the thought of opening up large Silverlight projects with DomainDataSources all over the place in XAML! This will make for the same ugly constructs with melding of UI-data that most of us have grown to hate in ASP.NET solutions floating around out here in the wild.

Gravatar

Hi Shawn - good comments, my thoughts:

On a recent 'proof of concept' small project with RIA Services we ended up just using a intermediary library to link the UI and Server projects - I agree that 'RIA Link' smells a bit of demoware and soon gets unweildy in a non-trivial solution.

For the RiaControls directly in the XAML we too ended up with a ViewModel class that took care of that, i.e. kept the presentation XAML clean, and a VM responsible for setting up the binding and talking to the model (which has become a thin layer over the DomainService client piece.

For validation we're playing with SharedCode (a 'by convention, it has the word 'Shared' in the name bit of magic!) to provide something over and above CustomValidator, and so far ok. Quite a bit of home plumbing here, which is never a good sign.

We found it a little confusing to try to merge some of the ideas of the 'RIA Business Application' VS template and then stripping it back and using PRISM. In the end, the only bits of PRISM to survive were really Unity for setting up testing - but that was more to do with that we didn't really need too much 'composite app' like views just yet. The other part of PRISM we tried to use was the DelegateCommand, but it was kinda clumsy.

- David


 



 
Save Cancel