This is kind of an interesting trick, and allows me to separate out all the RIA specific metadata from the original class definition. This makes total sense when you look at the way they handle LINQ to SQL, for example. In that case you already have Entity classes defined by the LINQ to SQL wizard, so this extra metadata class allows you to associate the right attributes without touching the (generated) LINQ to SQL classes. Clever. Notice that the metadata class uses fields, not properties, and just matches the names for the sake of simplicity.
In this case, the additional metadata defines data validation rules that get enforced both server and client side. There are other attributes to enforcing string length and ranges.
This bit goes in a file called Person.shared.cs, and it will be copied to the client project and compiled there as well as on the server. The [Shared] attribute marks the bits that need to be thus propagated. Again, clever. Of course, any such shared code has to compile in Silverlight.
With the Person entity all ready, I can expose it to the client by creating a new DomainService class with methods for Get, Insert, Update, Delete, etc.
PeopleData.Persons in this case is a List<Person> that’s populated with some sample data. The [EnableClientAccess] attribute causes the build-time bits to generate a client side proxy for calling the service without the client project needing a service reference. It really makes the Silverlight and the Web projects feel like parts of the same app rather than disconnected pieces.
The corresponding class that is generated on the client side is a DomainDataContext, which feels much like a LINQ to SQL DataContext only it’s lazy-loaded like the Astoria ones. The GetPersons method on the server results in LoadPersons on the client, etc. If I hadn’t implemented the Insert/Update/Delete methods on the server side, the DomainDataContext would simple behave like a read only data source. This model works really well with the DataForm class. If I set the ItemsSource of the DataForm to the Persons “table” in the client side data context, it will properly enable/disable the add/delete buttons depending on the capabilities of the data context. Neat.