Well, after realising (or even RIAlising if you like puns) that RIA services weren't cut out for non-Silverlight clients, I went searching for The Next Big Thing. Can't remember if I mentioned it, so I'll bore you by repeating it, but all of this investigation is for a big project I'm in that will need some sort of central data access point that can be used by all sorts of clients, most likely being WinForms, WPF (one of my colleagues is really excited about WPF), ASP.NET and Silverlight. Ideally, we want all of these to be able to use the same point of access for data, with the business logic behind that point of access.
RIA looked like the answer, but doesn't seem to play ball with anything other than Silverlight. So, I went looking at its big brother WCF. The idea was to build an end-to-end solution that had a WCF service on top of an entity framework model, and various clients consuming the service.
All went well at first (doesn't it always!). Building the service was surprisingly easy, as was consuming it in a WinForms and/or ASP.NET client. I tried the default configuration, which sends out objects that inherit from EntityObject, then moved on to adding a T4 template to generate POCOs (Plain Old CLR Objects). This has a big benefit over the first approach in that the objects sent out don't depend on the entity framework, and are more lightweight. The downside is that you lose the built-in change tracking, which is a shame.
With a big fanfare (well, not really, but you get the idea) I moved on to another T4 template, this time to produce STEs (Self Tracking Entities), which don't depend on the entity framework, but have change tracking built in. Now because WCF is a data service, the objects that get sent over the wire consist of the data, and not the methods. For this reason, you need to move the STE classes into a separate class library, so you can reference it on the client.
By the way, if this is all new or Chinese to you, I highly recommend Programming Entity Framework, as well as the MSDN entity framework videos, as these cover this stuff in detail.
Anyway, once I had the class library, writing a WinForms or ASP.NET client was pretty easy. I added a service reference to the WCF service, and away I went. Boosted by this success, I concluded that I had finally found the right combination of technologies. Ha, little did I know!
Where it all went wrong was when I tried to consume the same service from Silverlight. The first problem I encountered was that I couldn't add a reference to the STE class library in the Silverlight project, as you can only add references to other Silverlight projects, not plain old .NET ones (which, for the want of a better abbreviation, I'm going to call PODN - Plain Old Dot Net). Apparently this is more of a design issue than a technical one as, despite the claims to the contrary, Silverlight isn't really built on a separate framework from .NET, it's actually a byte-compatible one. With a little bit of fiddling, you can reference a non-Silverlight assembly in an Silverlight project. Whilst this works, I didn't really like the idea.
So, I experimented. The obvious solution was to build two STE class libraries, one in PODN and one in Silverlight. This failed miserably, I think due to the fact that the WCF service was trying to handle two different sets of objects at the same time. I got a cornucopia of exotic compiler errors that I never managed to fix, even after I removed the Silverlight class library from the solution.
After pouring out my tale of woes to Yossi, I gave up and went on to something else. He went off in search of other technologies, and I thought that was the end of it. It wasn't.
A rather excited Yossi called me yesterday to say he had spent far too much time on this problem, and had found out how to do it. Basically, it comes down to a bit of a fiddle, based on the way we think (probably totally inaccurately) how WCF works. As I mentioned above, WCF is a data service. I had assumed that it had an intimate knowledge of the classes it was sending out, and was therefore getting all mixed up about whether it was sending out PODN STEs or Silverlight STEs. It seems it isn't that clever, or at least isn't that worried...
WCF is a data service (did I mention this?), and all it seems to care about is being able to serialise the data at the server end, and the client being able to deserialise it. It doesn't actually seem to worry if you have the exact same type at either end, as long as the class members match enough to enable deserialisation. In other words, as long as there is a Customer object at either end, and that object has a Name property that is a string, WCF couldn't care if the class library is PODN, Silverlight or (possibly) any other technology you like.
So, all you need to do is physically copy the generated STE class files from the project that has the T4 template into a Silverlight class library, and reference that on your Silverlight client. Your WCF service doesn't know anything about this class library, as you copied the files without linking them. It thinks it's sending out PODN STEs, which it is. The client thinks it's getting PODN STEs, which in the case of WinForms and ASP.NET it is. However the clever bit is that you can generate a Silverlight class library, and then a Silverlight client will think it's getting Silverlight STEs. As the data side of the classes is the same in both cases, they can be serialised and deserialised without problems.
Yossi managed to build a solution with a Silverlight client and a WPF client using the same WCF service, even though they were referencing different class libraries.
The only downside to this is that if/when the model changes, you need to remember to copy the regenerated class files into the Silverlight class library and rebuild it. You don't get the automatic regeneration that you would have by linking the T4 template. However, until Microsoft come up with a better solution, it will do.
So, until we hit the next hurdle, we are back on track with WCF on the server and anything we like for the client.