Welcome to the first in a series of RIA Services How-To's. Unless mentioned otherwise, all these tidbits will use the latest drop of RIA Services (at the moment, this is the May 2009 drop). When new drops arrive, changes may have to be made, inherent to beta software.
But, first things first: how do you start using RIA Services?
Step 1: getting started
Start a new Silverlight-project. Assuming you've installed everything correctly (I'm using the May drop of RIA Services, SL3 beta, VS2008 SP1), you'll notice a new checkbox, "Link to ASP .NET server project".
If you check this checkbox, RIA Services will be enabled. You'll end up with 2 projects as usual: your Silverlight-app, and a webapp hosting this Silverlight-app. You'll notice extra references added to your project to enable RIA Services.
Tip: you can enable or disable this ability later on, by looking at the project properties of your SL app: you'll notice a combobox, ASP .NET Server Project Link. Here, you can select the webproject you'll want to link to to use RIA Services. This effectively means you can enable RIA Services on existing applications, simply by selecting a webproject from your solution.
Step 2: your datastore
You'll need to add some kind of datastore to your webapp. It doesn't really matter what kind of store this is: it can be an Entity Framework model, but might as well be some simple POCO classes with dummy data. The client (your SL-app) doesn't need to know what kind of datastore you have - it's totally unaware of this. I've installed the Lite version of the AdventureWorks-DB, and will use a few tables from it. So, I right-click my webapp and choose to add a new ADO .NET Entity Model, and select the Customer and CustomerAddress tables from AdventureWorksLT. I end up with something looking like this:
Step 3: expose your data
Here's where the magic begins! ;-) You need to expose your data to your SL-app. To do this, you need to create a DomainService. This is a new class, with which RIA Services will take care of sharing your data/methods across tiers. To add one, right-click your webapp -> add new item -> Domain Service Class. Give it a name, and you'll see a screen looking like this:
Of course, you need to check "Enable client access". :-) Next, select the datacontext you wish to expose. In this example, it's the AdventureWorksLT-model I created in the previous step. Now, you can select which enitities you want to add to your Domain Service. For each entity you select, methods will automatically be generated to read data from your datastore, and if you check "Enable editing", subsequent insert, update and delete-methods will be generated.
Tip: if you don't see your datacontext in the dropdownlist, build your application before adding the domain service class.
Last but not least, you can also check "Generate associated classes for metadata". When this is checked, a metadata-class will be generated, allowing you to do stuff like validation accross tiers, define how your data should look when using a dataform, ... I always check this option (do you know a lot of apps that don't require validation or don't require the need do define how your data should look? ;-)), but I'll go into detail on that in a future post.
Now, click "OK", and... magic! Visual Studio will start generating lots of code. On your webapp-side, you'll see your DomainService-class. It contains all the necessary CRUD-methods (GetCustomer, InsertCustomer, ...). You can add methods to this class, or change the existing methods as needed: this is the place where you'd put your application logic:
Now, build your solution. If you check "click all files" on your Silverlight-app, you'll notice a new folder, called, "GeneratedCode". This is essentially the client-side, generated code that corresponds with the server-side methods. It contains client-side versions of the classes (entities) you've exposed through your DomainService-class. It also contains a DomainContext, which is the client-side representation of your server-side DomainService. Through this context, you can access all the functionality of your domain service. You'll also notice the DomainContext containing Load-methods for your entity-lists.
Tip: the names of these methods are automatically generated - by default, an entity "Customer" will have a "GetCustomer"-method server-side, and a "LoadCustomer"-method client-side. If you want to choose what name the generated client-side method must have, you can use the [Query]-attribute. Check my previous post for more info on that.
Step 4: accessing your data from your SL-app
All necessary code has been generated, so now you need to access this data from your Silverlight-application. As I explained, on your client, Load-methods have been generated (methods like this will be generated for every method you write in your server-side domain service class which returns an IQueryable list). First, you need to instantiate your client-side generated DomainContext. You'll notice that that instance contains the generated Load-Methods, and also collections of your entities (eg: the Customers-property is actually an EntityList of Customer):
Now, you want to call the client-side LoadCustomer-method to load the customers. When this statement is executed, the GetCustomer-method on your server-side DomainService will be executed.
To display the data you've got in your app, bind it to, for example, a datagrid. You'll end up with something looking like this:
And you're done! ;-) As you'll notice, you've also got events on your DomainContext like Loaded / Loading / PropertyChanged: you can add Event Handlers to these as needed.
Step 5: adding, deleting, updating your data
Next steps are of course deleting, adding, updating, ... your data. This is actually quite simple: what you need to do is manipulate the EntityLists you've got in the DomainContext on your client side: Customers, for example. Add elements, update elements or delete elements from that list. Now, your DomainContext instance has a method called SubmitChanges & RejectChanges. As you might have guessed by now, executing the SubmitChanges-method will persist the changes you've made on the collections to your database (it will call the corresponding server-side methods for this automatically). RejectChanges, well, rejects your changes ;-) There is, of course, much & much more to this - you can work with transactions, changesets, check for changes, et cetera - more on that in one of the next articles.
That's it! This article should've covered the basics of working with RIA Services. I hope this helps some of you out - check back regularly for more! ;-)
A word of advice: RIA Services is beta-software, and lots of code gets generated automatically. In most scenario's, you'd want to split your Domain Services into another namespace (or even assembly). However: this doesn't really work as you'd expect at the moment of writing. You'll notice code generation going bonkers when trying this, so for now: just keep everything in the same namespace. I assume (hope ;)) this will be fixed in future drops.