Now that it's post PDC09 I've decided to take some time to migrate some of the code that I have in my SocialBus project from standard WCF and DTO's over to RIA services. The SocialBus project is something I've been working on as an evolution of back end of the TweetZenn client I was building before. What it will provide is a unified interface to various social networks; right now that being just Twitter and Yammer.
Up to now I've built it with standard WCF services. This always had a problem that bugs me to now end. In the solution I have "Model" classes for the domain, and the service calls return those model objects to the client. The problem is that to use the service in Silverlight, the proxy generator builds new classes based off of the WSDL from the service. These classes look the same from the perspective of properties, but they are:
- In a different namespace
- Lose any methods to perform manipulations of the data in the objects
What this is in all actuality is an implementation of the Data Transfer Object pattern implemented by visual studio. It's problematic for the reasons mentioned above, as well as if you build any libraries that use the model objects, the objects you have in the client are actually not the objects in the library, and it won't work.
A typical scenario to solve this is the following:
- Cross-compile the model code in Silverlight, and
- Project the DTO objects into the silveright versions of the model objects
Well, this works fine, but it's a real pain in the butt. Every model object's .cs flle has to be added as a link into a Silverlght project. First, this is real fun with the Silverlight and non-silverlight libraries get out of sync because you forgot to add a link to a new class. Second, you are doing all these projects. Sure, LINQ makes it real easy, but why can't I just use my object as I defined it the first time!?!?
Well, WCF RIA services is supposed to solve all of this. I've played with it a bit in the last week and decided to really start using it. Note, I tried the CTP and had too much trouble with it, but those issues seem to be solved. So, I'm going to stick it in a real project now and give you some tips on how to use it.
Now, this may not be the most elegant way of doing it. It's what I'm doing to learn more. Also, I am using POCO, which is for the most part very sparsely documented and not in a manner of how I want to use it. Finally, yes, I use LINQ to SQL on the backend, and I could just move to LINK to EF and use RIA to move the entities to the client. However, this has issues to me that are not obvious yet in this solution; so yes, I could do it and things would be easier for purposes of this demonstration, but it is not in the long run so I'm just going to use LINQ to SQL for that database access and project them into the domain model POCO objects for passing back by RIA (also note that client side I am not planning to need any entity tracking, so that lack of functionality also makes EF an amount of overkill).
To start out, the solution looks like this:

What we need to do is add a WCF RIA Services Class Libary to the solution (I'm putting it in a solution folder named 'RIA' - which is already shown):

This creates two projects in the solution:

The Class1.cs files are not needed so I will delete them as I'm going to use an existing C# library instead of adding new classes to these projects. This is one area in existing documentation that is not clear as it always mentions to add new classes to these projects. What if I have existing classes in another assembly and I don't want to duplicate effort (Dont Repeat Yourself - DRY)? Well it's okay as it works fine and I'll show an example of it.
Anyway, what are the purposes of these two projects?
The project that ends in '.Web' is where we will place our RIA domain service(s), which will eventually be exposed as WCF services (I'd say web services, which used to be true, but there are other potentials now too). This project can be linked into your web project for you Silverlight app and the service(s) defined by the domain service classes will be exposed from that web site. Also, in most examples on the web, you also put your domain objects in this solution. Since I've got them declared already, we'll only be putting domain services in here.
The other project is where the RIA services extensions in Visual Studio will auto generate code for Silverlight based applications, which includes both service proxies, as well as Silverlight based versions of your domain objects. This code generation is done by the extensions by examining the attributes on classes in this solution (and it turns out any referenced assemblies) post compile.
This is really convenient for the following reasons:
- You don't have to manually create the proxies through add service reference,
- You never have to regenerate proxies when changing the service interface (the code is always regenerated),
- The domain objects are in the same namespace as you gave them in wither the .web file, or in our case the assembly that we already have written, and
- The signature of the Silverlight objects will be the same, and given the correct use of RIA attributes, will also have any methods that you define for client side business logic.
Well, I'm thinking I'll break this into a number of parts as it appears this will be involved. In the next post, I'll write about how to create and consume a really basic domain service thereby showing how RIA makes this all work.
70243032-00f1-4c87-80fa-c22f2b134bdd|2|5.0