Wednesday, 8 August 2012

3. Silverlight + RIA Services – Client


Having taken a look into the service side of WCF RIA Services, lets have a look into the client side. If I have the following DomainService – 
public class MyDomainService : DomainService
then what we have at Client Side is the DomainContext. The build process leaves us with a generated class MyDomainContext on the client side which derives from a framework class DomainContext. 
What’s a DomainContext? It’s quite a big class – 

I brought in the DomainContext’s friends – DomainClient and EntityContainer onto that diagram.
The DomainClient
Of these, I think that the DomainClient is easiest to understand. From previous investigations we know that a RIA Services client submits 3 fundamental kinds of operations to a RIA services service;
Query 
Invoke 
Submit 
and it’s the DomainClient that knows how to do the client<->server communication for Query, Invoke, Submit asynchronously with cancellation. The DomainContext then is abstracted away from the details of how these operations are transmitted to the server side by relying on the DomainClient to do that work.
Now, the particular implementation of DomainClient that we find in the framework – WebDomainClient - is a specialisation of this class that knows how to communicate with a default RIA Service endpoint. 
That is, one that’s using XML, binary encoded over HTTP/HTTPS. 
If I wanted my client to communicate with another endpoint such as a SOAP endpoint then I’d be looking to write a DomainClient that knew how to do that and then I’d plug that implementation into a DomainContext. For me, this means that when I’m using a non-default DomainServiceEndpointFactory on the service side I should expect to be looking to write a DomainClient on the client-side.
The DomainClient needs some fairly complex data in order to be able to do its core Query, Invoke, Submit functionality. Taking a look at the signatures, Invoke looks like the simplest;
public IAsyncResult BeginInvoke(InvokeArgs invokeArgs, AsyncCallback callback, object userState); 
where an InvokeArgs is a fairly simple class;

which “just” captures the operation that we’re trying to invoke server-side and the parameters that need to get passed to it.
What about Query? The signature looks like;
public IAsyncResult BeginQuery(EntityQuery query, AsyncCallback callback, object userState); 
where the details of the query to be performed are captured in an instance of EntityQuery;

note that the Query property above is an IQueryable. 
Finally, what about Submit? Submit in some ways feels the most complicated. The signature looks like;
public IAsyncResult BeginSubmit(EntityChangeSet changeSet, AsyncCallback callback, object userState); 
and the “payload” here is the EntityChangeSet class;

where each of those [Added/Modified/Removed]Entities properties is collection of Entity ( more to come on that later ) whereas GetChangeSetEntries returns an enumeration of ChangeSetEntry;

that’s quite a complex class but I think it’s used both as an input to the Submit operation and as an output from the Submit operation in the sense that the EndSubmit method;
public SubmitCompletedResult EndSubmit(IAsyncResult asyncResult); 
returns a SubmitCompletedResult which itself has an IEnumerable<ChangeSetEntry> called Results so the class kind of serves ( at least ) two purposes as it’s being used in the two different directions of data flow from client->server and then back again.
The EntityContainer
What about an EntityContainer? Right now I don’t have any entities in my project so the generated EntityContainer is a little on the “empty” side;

By the way – this MyDomainContextEntityContainer class ends up generated as a nested class inside of the MyDomainContext class and I also see that MyDomainContext has a generated override of CreateEntityContainer which looks like;

and so that all links up very logically.
What if I had some entities service-side. Let’s add one so that my service-side code looks like;

and now on the client-side the generation process spits out some different things. Firstly, I now see that I have a different EntityContainer;
internal sealed class MyDomainContextEntityContainer : EntityContainer 

and the constructor is using the base class CreateEntitySet method to create an EntitySet<Person> and add it in to the EntityContainer.
I also get something derived from Entity – my Person class;

I pasted all the code in there as I think it’s worth looking at. We have these 3 classes – EntityContainer, EntitySet<T> ( where T : Entity ) and Entity working together on the client side.
EntityContainer
EntityContainer is largely a dictionary of <Type,EntitySet> and mostly delegates its work down to the EntitySets that it contains. So, you can walk up to it and ask for EntitySet<Customer> or EntitySet<Order> and so on.
It implements property changed notification and also IRevertibleChangeTracking. If I quickly derive my own EntityContainer like this one below;

then I can write code against the “change tracking” functionality as in;

but largely this is the work of the contained EntitySets being co-ordinated by the EntityContainer to work together, I don’t think there’s a huge amount of work that the container itself is doing here.
In terms of how an EntitySet gets into the container – I think the only way is to call EntityContainer.CreateEntitySet() and that’s protected so you would need to derive an EntityContainer like I did with my example PeopleContainer there in order to do that. 
Normally, there’s no need to do that because that’s what the tooling does for the entity sets that it “sees” exposed by the server-side when it code-gens an EntityContainer derived class for the client-side.
The EntityContainer also has methods called LoadEntities where you can pass a whole collection of Entity ( of mixed types ) and the EntityContainer will loop through and make sure that each Entity gets dropped into the EntitySet<T> for that particular Entity type.
As part of loading you can opt for whether the Entity that’s being loaded will;
be ignored if an Entity with the same ID is already present in the EntitySet 
overwrite an existing Entity with the same ID in the EntitySet even if that Entity has been modified 
overwrite only unmodified properties of an existing Entity with the same ID in the EntitySet 
EntitySet
The EntityContainer contains a bunch of EntitySets. There’s the EntitySet class and its derived class EntitySet<T>. As the name suggests, this is a set of Entity of a particular type that also supports property change notification and revertible change tracking along with collection changed notification. 
An EntitySet can be associated with an EntityContainer and ( so far as I can work out so far ) the only way to do that is to have the EntityContainer create the EntitySet via the EntityContainer.CreateEntitySet<T> method which creates the EntitySet<T> and sets its EntityContainer property to the right value ( i.e. the owning EntityContainer );

I guess the properties/methods largely speak for themselves with the possible exception of Attach/Detach which feel familiar to me from [LINQ to SQL/LINQ to Entities]. If Add() means “treat this as a newly created entity” then there needs to be a method that means “treat this as an entity that already exists” and Attach() looks to have those semantics.
Entity
EntitySet contains a bunch of Entity objects. Entity is quite an interesting class – it’s an abstract class so the intention is that you derive from it and it implements a whole slew of interfaces;

and so an Entity is an object that supports;
property change notification ( fairly standard ) 
being an editable object ( fairly standard too – I’ve used this before in combination with the DataForm ) 
the new validation interface from Silverlight 4 – INotifyDataErrorInfo ( fairly standard when you’ve seen it but a little bit painful to implement ) 
the notion of change tracking via IChangeTracking and the idea of reversing those changes via the derived IRevertibleChangeTracking 
and so I can write code that makes use of the ability of the object to track changes and so on such as;

and it’s clear that the Entities involved here go through states represented by their EntityState property depending upon what’s been done to them and there’s also the notion of the original values being accessible ( for the entity that I Attached because it perhaps doesn’t really make sense for the Entity that I Added ) and then being able to Accept or, in this particular case, RejectChanges to get back to where I started. 
Entity manages to do this kind of change tracking because it has methods RaiseDataMemberChanging and RaiseDataMemberChanged so it’s possible for the base class implementation to be aware of before/after values and track the changes being made.
What else can Entity do? 
Validate
It has capabilities for validation. By default ( i.e. if you don’t override ) this is based on the System.ComponentModel.DataAnnotations attributes ( and custom variants of those ) so if I updated my Person entity on the server side to be something like;

then I might write a little client-side code;

and, because the property setter for FirstName includes a call to the ValidateProperty() method, that causes validation to fire and so I have validation errors once that property set has completed. I could find out more about those errors with code like;


and they also surface via the Entity class implementing INotifyDataErrorInfo so I could use that interface to determine similar information.
Validation capabilities in RIA Services are not tied to only the built-in attributes from System.ComponentModel.DataAnnotations – you can do a whole bunch more around custom validation at both the property and the entity level. 
I’ll follow up on this in a later post but as an example if I wanted to do a little cross-field validation on my entity by adding this code on the server side ( to a file called PersonValidator.shared.cs in order to share that code with the client-side );

and then applying that attribute to my Person entity on the server-side;

then I can write client-side code to exercise this a little as in;

and so the Entity class clearly has validation capabilities.
Invoke A Custom Update Method
The Entity class also has these intriguing methods/properties (protected) called InvokeAction, IsActionInvoked, CanInvokeAction and an enumerable EntityActions property.
What’s this about? It looks to come down to the ability to specify custom update methods to be called server-side at the time of a SubmitChanges call.
As an example, I can write some method called Foo on the server-side like this one added to my domain service;

and one of the ways that manifests itself on the client-side is by these additional generated methods on the Person class;

So, the method call Foo() that we make is turned into a call onto the base-class Entity.InvokeAction() method. 
The base-class effectively captures the details of the method call made ( including parameters if we had any ) such that those details can later be retrieved from the Entity. 
In the usual scenario this is used by the DomainContext in order to defer the server-side invocation of the method Foo until DomainContext.SubmitChanges() is called when the corresponding server-side functionality will be invoked as part of the whole SubmitChanges cycle.
Sticking with my made-up PeopleContainer class on the client-side I can write a little code against this functionality such as;

and we can see that by calling Foo what I’ve actually done is to set a flag to say that Foo has been invoked, that it cannot be invoked again ( right now ) and the framework has stored the fact that I called Foo into the EntityActions collection.
Whilst EntityActions is a collection, as far as I can tell it only supports the notion of a single custom invocation being outstanding at any one time.
So, we have this notion of “capturing” a method call on an Entity instance along with the parameters that it was invoked with ( not shown here ) such that the other componentry can later invoke the corresponding server-side functionality.
All in all, EntityContainer, EntitySet and Entity are pretty useful classes to have around on the client side providing a lot of functionality for us that we’d otherwise have to write.
The DomainContext
What’s left for the DomainContext then, given that;
the EntityContainer deals with storing all the Entity instances into neat little organised sets and has capabilities for change tracking, validation and so on 
the DomainClient deals with the logistics of making sure that Query, Update, Invoke operations get from the client-side to the server-side and back again. 
Largely – I think it glues these other two types together. 
It does some work in its Load methods to use the DomainClient in order to load the entities for the EntityQuery from the server-side and it takes the results of that operation and pushes them into the EntityContainer via its LoadEntities method.
It also does a bunch of work around its SubmitChanges method to communicate with the EntityContainer and determine what changes have been made to the data before building up an EntityChangeSet to pass through into the DomainClient and get those changes submitted across to the server-side.
It also provides a place for the code-generation tools to work upon in the sense that if I have a domain service;

and the generation process does quite a lot to take MyDomainContext and derive it from DomainContext.

It’s reasonably clear that the Persons property is just reaching into the EntityContainer for the right EntitySet<T> and that when we perform a MyDomainContext.Load() using the results of MyDomainContext.GetPeopleQuery() then the DomainContext will use the DomainClient to grab the data from the server-side and then drop the results into the EntityContainer again.

Monday, 6 August 2012

2. Silverlight + RIA Services – Services

What tooling is doing – LinqToEntitiesDomainService<T> based on Entity Framework model derived from DomainService where T is our LINQ to Entities ObjectContext.
Now let’s dig into this - DomainService is an abstract class with no abstract methods but lots of things to override;
Note - Sometimes you don't want to give the possibility to instantiate a class but you need this class as a base class for other classes. So we can have abstract class without any abstract method.



There’s quite a lot of functionality in there relating to ChangeSets such as;

ChangeSet property 
AuthorizeChangeSet() 
ExecuteChangeSet() 
PersistChangeSet() 
Submit() 
ValidateChangeSet() 
There’s functionality that looks to relate to querying such as;

Query() 
Count() 

and then there’s the notion of “invoking” something;

Invoke() 

and then some additional pieces around all of this like;

Initialize() 
OnError() 
and various pieces of contextual information such as ServiceContext, ServiceDescription, ValidationContext, AuthorizationContext 

and so there’s quite a lot in this one class.

If I create DomainService like my ExampleDomainService here; We get the following DomainService


 along with the necessary references ( System.ServiceModel.DomainServices.* at least ) to make this build. In my web.config file I also noticed that a module is added to the pipeline – DomainServiceHttpModule - and ASP.NET compatibility is turned on for System.ServiceModel.

So, what’s the role of the DomainServiceHttpModule? It uses a VirtualPathProvider in order to dynamically make available service(s) that it constructs from DomainService derived types that it finds in the referenced assemblies of the application.

You can see this ( if you’re following along ) by visiting the equivalent of;
http://[VROOT]/Services/WebApplication1-ExampleDomainService.svc

where VROOT for me was localhost:27544 because I was serving up my web application project via Cassini on port 27544.

That SVC file is dynamically generated rather than being something that has to physically exist in the project and the dynamically generated SVC file ends up looking something like;

<%@ ServiceHost Factory=”DomainServiceHostFactory” Service=”ExampleDomainService” %>

and so this factory is used to bring in a custom service host for WCF ( DomainServiceHost ).

The DomainServiceHost knows how to perform a few tricks including;
1. Generate a service description for WCF from your DomainService 
2. Generate a set of endpoints for WCF from your DomainService 

In terms of the service description, the built-in way that this happens is by reflecting over your DomainService class looking for particular kinds of operations exposed publicly from that class. The set of operations that are looked for and the shape that they need to have are listed up here but the basic idea is that the framework code is looking for;

Query operations 
Insert operations 
Update operations ( these fall into 2 categories of “Update” or “Custom” ) 
Delete operations 
Invoke operations 

and then building a service description based upon what it finds. 

In terms of the endpoints, the DomainServiceHost makes available a default endpoint over HTTP (or HTTPS) using a binary encoding and it also adds in an authentication scheme based on what it sees being used by the default webHttpBinding that you have configured. That is – as an example, if webHttpBinding is using “Windows” authentication by default then the default endpoint will do the same.

My request for WebApplication1-ExampleDomainService.svc above was met with an error;
“ContractDescription 'ExampleDomainService' has zero operations; a contract must have at least one operation.”
which makes sense in that my DomainService has no functionality available on it. 

The simplest thing I could do is to add an operation to it and the simplest kind of operation that I can add is an Invoke operation because those are closest to standard WCF service operations in that they are calls from client to service that are simply executed ( asynchronously ).

I could add an “Invoke” operation;



and then my service no longer complains when I visit its URL at WebApplication1-ExampleDomainService.svc;




Now – I can’t get WSDL for this endpoint even though there’s a link there. That’s not the intention for this default endpoint.

This default endpoint is for easy access from a WCF RIA Services client. It’s possible to expose other endpoints for access from other clients ( I’ll return to this ) but this endpoint is the default one and is targeted at easy, efficient calling from a WCF RIA Services client.
On the client-side the generation process will make a corresponding ExampleDomainContext class that knows how to “talk” back to my service with public members on that class that cause the invocation of my Add method server side. That means that I can write code such as ;



and that all works fine and calls my service-side operation for me without any additional steps.
It’s interesting to note what kinds of interaction this call from the client drives with my ExampleDomainService class on the service-side here. If I were to override the methods Initialize() and Invoke() then I’d see them being called as these pictures from the debugger shows;




you can see that I’m authenticated ( interesting! I’ll return to this ) and that the operation type is an Invoke. We next arrive in my override of the Invoke method;


which is being called with the method that the client side wants to invoke and the parameters for that method. Then my actual Add method would be invoked, the return value gathered and sent back to the client. So, the DomainService has a sort of “life cycle” for handling client-side calls and here the invocations coming from the client cause the service-side code to go through a cycle of Initialize->Invoke->MyMethod.

Now, whilst this ease of calling without an explicit service reference has some advantages over just using raw WCF it’s more likely that we’d want to expose sets of entities for the client to operate on and we see a lot more benefit in doing that. So, if I have an entity such as; it feels like I should be able to write a method that matches the pattern for a query operation such as;



but that won’t work even with my made up test entities being returned. The framework needs an entity to have a Key defined to tell it how to identify an instance ( not unreasonable ) and so I might do; and then make sure that the Key is set up ( notice that I keep returning the same keys here for repeat invocations );


and then I can query against that from the client side – for example;




It’s kind of interesting to see what flows across from client to service in this instance – taken from Fiddler;


where we can see that the request was encoded into the query string and the response;



was binary encoded but the important point is around the client’s automatic ability to communicate with the service – not the particular protocols that it uses to do it.
It’s also interesting to see the invocations made onto the DomainService and, once again, if I override a few methods and use the debugger I can see that when the client runs a query I see a call to Initialize() on the newly constructed DomainService and then;



a call arrives into the Query method and you can see that the Method is specified and the Query is specified and IncludeTotalCount is specified – it’s all come into the call.
Then the base class implementation here will take that and route it to my method GetPeople() to actually get the data that is then used as the basis of the query which can then be executed and the results returned to the client. What about if we want to modify data? At the moment, my ExampleDomainService doesn’t support the idea but I could add a few empty methods to it to at least give the impression that it can support modifications;



Ok, so now when I rebuild I see a change on the client side.
Previously, I noticed that the DomainContext on the client side has a generated override called CreateEntityContainer and in my case this is creating an instance of a generated class called ExampleDomainEntityContainer.
Now, prior to my addition of those 3 new methods service-side that class looked like;


but after the additions I now see;



and so that EntityContainer is allowing modifications to my Person entity set so I can write code on the client side that attempts inserts/updates/deletes such as;


where we are doing a single delete, a single update and a single insert. Note that nothing crosses the client/service barrier until we hit the SubmitChanges call on line 19 above. At that point, we see the service-side ExampleDomainService get instantiated and then its Initialize() method is called as we’ve come to expect. From there, the calls are;



and so you can see that we get a call to Submit() and what’s been sent from the client side is a ChangeSet and the debugger clearly shows that the ChangeSet contains one insert, one update, one delete. So, the methods that we’ve written ( InsertCustomer, UpdateCustomer, DeleteCustomer ) are not “directly” called from the client side but, instead, are routed through Update which drives a “life cycle” of method calls - next we see a call to AuthorizeChangeSet;




and you can see that the ChangeSet in progress is represented in this.ChangeSet for access. There’s also the AuthorizationContext property which is null in this case ( more on that in a later post ).From there, we move to ValidateChangeSet;



and from there to;



and then the base class implementation causes my InsertPerson, UpdatePerson, DeletePerson methods to be called to do their work before making these changes final by calling;


so there’s a whole set of interactions driven by the arrival of our ChangeSet into the Submit method on our ExampleDomainService and the DomainService is really offering three things here as service operations;

Query 
Invoke 
Submit 

There’s another aspect to Update in that there’s a notion of a named update operation. If I was to add a named update operation to my service such as;


then that can be called on the client side via one of two mechanisms – it shows up on the generated ExampleDomainContext as you’d expect but it also shows up as an instance 
method on the generated Person entity on the client side so that I can change my client code to add;


adding that call to OperationOnAPersonWithNoSpecialNamePrefix on lines 17/18 and then the service-side interactions from this are;

ExampleDomainService::ctor 
ExampleDomainService::Initialize() 
ExampleDomainService::Query() 
and that satisfies the query and then for the Submit call we see;
ExampleDomainService::ctor 
ExampleDomainService::Initialize() 
ExampleDomainService::Submit() 
ExampleDomainService::AuthorizeChangeSet() 
ExampleDomainService::ValidateChangeSet() 
ExampleDomainService::ExecuteChangeSet() 
InsertPerson(), UpdatePerson(), DeletePerson() 


and then my named update operation is called;


followed up with a call to ExampleDomainService::PersistChangeSet() at the end of the cycle.
Up until now, my service has only offered the single entity set Person but it’s pretty likely that we’d have related entities in the model that I’d want to expose. Perhaps Person can have a set of addresses.


Note that in order to relate entities, I have the Address.Id property but also the foreign key of Address.PersonId which links back to the “owning” Person entity. There’s also an attribute 
[Association] which I’ll apply to my Person entity which tells the framework which properties to look at in order to determine these key values.

The framework also needs a bit more help in the sense that it needs to know whether the Addresses belonging to a Person are there for server-side programming or to be included 
down on the client-side. This is done via an IncludeAttribute. 

With that said, I can modify my Person entity in order to add the [Include] attribute, the [AssociationAttribute] and to make sure that each Address instance has the right PersonId 
foreign key set on it;


you might also notice one other attribute has crept in – the CompositionAttribute. What’s that for? Well, there’s a very good explanation here but what it’s essentially saying is that (in this model) the Person owns the Address and so (e.g.) removing the Address from the Person means the Address needs to be deleted – it doesn’t exist in its own right.

If I then add some CRUD operations to my ExampleDomainService for my Address entity;


and make sure that my test entities returned from my GetPeople() query are created with the right flag such that they create dummy Address data;


then I can code against it on the client-side – iterating through the Persons/Addresses in the standard manner;


where it’s worth noting that this is one query to the service rather than one for the Persons entity set and then one for each set of Addresses belonging to them ( i.e. Addresses are not being lazily loaded here ).


And I can also do some inserting, updating, deleting from the client side – for example;


and so this is removing 1 address, updating a second address and then adding a new person with a new address. On the service-side when we hit  ExampleDomainContext::ExecuteChangeSet I see calls to my methods;
InsertPerson ( for the new Id = 6 with the Addresses property populated to the created Address on line 12 with Id 61 ) 
InsertAddress for that Address 
UpdatePerson for the Person with Id = 1 which has 2 Addresses attached to it because 1 was deleted client side 
UpdateAddress for the Address which was updated on line 4 above 
DeleteAddress for the Address which was removed on line 3 above 
so my client-side work gets nicely replayed to my service-side and if I had a proper data access layer under these classes then it would do something with my data-store to actually 
make these changes live.


This post has got long but there’s one last thing I wanted to squeeze in. The RIA Services Client<->Service communication is largely automatic and the focus is on getting the functionality built rather than worrying about protocols and so on underpinning it.
However, that doesn’t mean that you can’t access these services from elsewhere and there’s a few ways of doing it. Within the RIA Services framework itself, there’s support for 
offering access over OData and you can do that by altering your configuration file. If I modify my config file to add a custom configuration section for domainServices within system.serviceModel as in;


and then also use that configuration section in order to request an OData endpoint;


then I can visit my service at WebApplication1-ExampleDomainService.svc/odata/ ( notice that trailing slash there because it seems to matter a lot ) and I see;


so – no collections exposed there but in order to expose collections such as my Person data I need to tell the framework which is the default query for that entity type which involves 
changing my ExampleDomainService class; and now when I visit my service I can see;


and I can then navigate into that dataset as in;



but I’m not sure that I can take that further by adding ( e.g. ) additional parts to the query such as indexing into the data by primary key or starting to build up expressions including $top, $skip, $filter, and so on.

An OData endpoint is just an example here though. It’s possible to expose other kinds of endpoints for other kind of clients. There are two more possibilities within the RIA Services Toolkit ( SOAP and JSON ) or you can write your own.
So, to offer up a SOAP endpoint I can dig into my RIA Services Toolkit and change my configuration;

and now I’ve got a SOAP endpoint that I can hit against and if I visit my service for a WSDL file which in my case involves hitting;
http://localhost:27544/WebApplication1-ExampleDomainService.svc?wsdl
then I see WSDL;


and I can go and do an Add Service Reference against that from Visual Studio (or some other IDE or tool) and start to work with my service in that way.

Friday, 27 July 2012

1. Silverlight + RIA Services - Overview

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.

Common Silverlight application architecture looks something like this -


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

all of these technologies are “data transfer” technologies in that they move some bits from A to B.

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.