A big part of the Silverlight 4 release is the new WCF RIA Services framework.
Its worth pointing out that WCF RIA Services doesn’t only target Silverlight clients – it also targets AJAX clients but I’m sticking with the Silverlight side of the house here.
Almost every Silverlight application spans physical computing tiers in that you usually run a Silverlight application from a website and it then makes calls back to services on that website ( the so called “site of origin” which has particular security implications ) or to other websites ( “cross domain” requests ).
NB: It’s possible to write a single tier Silverlight application with Silverlight 4. You could sit and write an application like “Notepad” for example which is installed from a USB key and simply interacts with the local filesystem. But this is a more “niche” use of Silverlight than the common use which is to install from a browser and then call web services.
This means that you end up with an application architecture something like the picture below;
where you have the Silverlight application code on the left hand side of the diagram displaying UI and running application logic and then ( at least ) a bunch of application logic and data access code on the right hand side.
Between the two is “the gap” that has to be spanned by some kind of distributed application technology and there are various possibilities in Silverlight such as the following listed in the order in which they are layered on top of each other;
- Sockets ( both TCP streaming and UDP multicast )
- HTTP ( via the WebClient and HttpWebRequest classes )
- This might be achieved by passing backwards and forwards XML and there are various technologies in Silverlight to help with that such as LINQ to XML, XPath, XmlReaders/XmlWriters, XML Serialization, WCF Data Contract Serialization
- Or you might look to JSON and there are technologies in Silveright for dealing with that such as the “LINQ to JSON” technology and/or the JSON serialization technologies
- Windows Communication Foundation ( WCF )
- Via HTTP
- Built-in support doing text/binary encodings over HTTP(S)
- Built-in support for authentication via transport mechanisms ( i.e. integrated authentication via basic, digest or NTLM ) and via SOAP mechanisms ( i.e. “transport with message credential” )
- Via TCP
- Offering the WCF duplex programming model for binary message transfer albeit without security support
- Via HTTP
all of these technologies are “data transfer” technologies in that they move some bits from A to B.
They don’t really help you with respect to building application functionality on top of the code that moves bits from A to B and nor do they help you in terms of guidance around how to structure the application code in order to make that happen.
It feels relevant to me to note that WCF offers a much higher level of abstraction than (say) raw socket programming in that you generally author services that are described in terms of a service contract and then offered over some binding that builds up the transport, encoding, security options and so on. On the client side you’re typically using metadata offered by the service in order to use tools to build up proxy classes to access the service.
It’s interesting how this combination comes together – with the right framework pieces and the right tools you can get to an abstraction that makes distributed programming far more productive.
On top of the WCF stack there’s also the WCF Data Services stack which offers OData compliant clients and services.
WCF Data Services is very data-centric in that you decide on that data that you want to expose and WCF Data Services exposes that for you in a RESTful manner as a number of AtomPub collections that you can then query into using OData’s URI syntax.
The services that you produce can be pretty much accessed from any platform and any client as you can see by taking a look at the consumers section on the OData website.
Whilst the focus is definitely on the data, WCF Data Services also makes it possible to expose arbitrary server-side operations as additional functionality and to intercept incoming operations and/or queries in order to add business logic but the primary intent is to expose data as the name of the technology suggests.
Silverlight is just one possible client for WCF Data Services and the client library does offer some higher level abilities than basic CRUD over entity sets with capabilities such as;
- ability to turn LINQ formed queries into URI based syntax compatible with OData
- automatic tracking of changes made to entities ( and entity sets ) returned from WCF Data Services to make for automatic submission of changes
- ability to deal with concurrent updates and the errors/retries that are needed to deal with those situations
- batching of queries/modifications to the server
but the level of shared knowledge ( “coupling” ) between the client and the services is still very low.
Typically, the client developer adds a service reference to a WCF Data Service and the “shared knowledge” between the client and the service is downloaded in the form of the service metadata which describes to the client;
- the “shape” of the entities that the service exposes
- the entity sets available
- the relationship between entities such that those relationships can be navigated
but that’s about the extent of it. There’s nothing shared about ( e.g. ) how to authenticate with the services, how authorisation might be performed by those services, how validation might be performed by the services etc.
There are upsides and downsides to this degree of separation – the potential for a variety of different clients and for independent versioning of the client/service are on the upside and productivity is a likely downside as you deal with the complexity of writing application logic on both the client and server side of the equation and code that shuffles collections of entities backwards and forwards whilst preserving state around whether they’ve been modified or not.
WCF RIA Services bridges “the gap” in a different, higher level way by embracing the idea that the client and the service are part of an application rather than separate clients and services that come together over an agreed contract.
Consequently, in a RIA Services application there is the tooling and framework support for sharing a richer set of artefacts between the client and the service than you’d see with a solution built around something lower level like a pure WCF solution allowing for a lot less friction in terms of;
- making the service-side data model entities visible to the client side code
- offering the ability for the client-side code to construct queries ( via LINQ ) which are then serialized, sent to the server for execution with the result-sets then returned to the client including the ability to add sorting, paging into those queries
- offering automatic tracking of entity changes and entity-set changes on the client side
- offering easy mechanisms for submitting client-side changes back to the server side and handling possible update failures
- offering the ability to specify validation constraints and have them applied both client- and service-side
- offering the ability to share arbitrary code between the client and service
- offering the ability to easily share ASP.NET services such as membership, roles, profile with a Silverlight client
I want to dig in to WCF RIA Services a little more over future posts but I thought for now it’d be good to start with a “magic demo” which illustrates the sort of speed that WCF RIA Services can give you when combined with Visual Studio 2010.
This is a version of the demo that I did for UK TechDays as part of the “Visual Studio 2010” talk but I thought I’d drop something similar here as a way of starting to illustrate some of the things that WCF RIA Services can do for you and the focus here is a little more around WCF RIA Services than around Visual Studio 2010 tooling;
Update – a number of comments came in asking for the source code for this video. I had deleted it but fished it out of the recycle bin and so here it is. Note that this was never intended to be shared – it was just built up as we were going along with the sample here and I don’t claim that it’s “best practise” or anything other than just put together to make the video.