Watch recordings of Brian's WCF RIA Services webinars:
This article is Part 1 of the series WCF RIA Services.
Introduction
In order to build serious business application in Silverlight (and other client technologies), you have to work with a lot of data. And that data is usually not resident on the client machine, it is usually distributed amongst many clients and is stored and operated on by back-end services. If you try to write this kind of application architecture yourself, you have to tackle a lot of technologies and write a lot of plumbing. In the end, most of what you are doing is pushing and pulling data from the client to the back end and invoking operations on the server from the Silverlight client application. What would be great is if most of that plumbing and push-pull logic could be automated for you, allowing you to just focus on what data you need, the rules that surround the manipulation of that data, and how to present it in the client application.
This is exactly what WCF RIA Services does for you. WCF RIA Services is a new part of the .NET 4 and Silverlight 4 frameworks that lets you quickly build N-Tier Silverlight client applications without needing to focus on the service plumbing to get data into and out of your client application from back-end services, logic and data access. This article and the subsequent articles in this series will get you up and running with all the capabilities of WCF RIA Services.
RIA Services helps you to write one set of server code, but have appropriate parts of that service code available on the client without having to duplicate it or write client side code to access it. On the server side, WCF RIA Services helps you define your services, domain entities, and supporting logic. On the client side, WCF RIA Services code generates corresponding classes that let you easily call those services, have the same entities available and populated on the client side, along with supporting validation logic and other kinds of code that you can share between the client and the service side. The diagram below shows what part of your architecture WCF RIA Services focuses on.
To see this in action, in this article I’ll do a quick run through of the basics of WCF RIA Services. In subsequent articles in this series, I’ll dive into more details of what is going on under the covers and how to adapt from the simplest usage of WCF RIA Services I’ll show in this article, to more real world scenarios. In those later articles I’ll dive into things like security, validation, concurrency, customization, and combining WCF RIA Services with other practices such as the Model-View-ViewModel (MVVM) pattern and unit testing.
But first we need to cover the basics. The application I’ll be using in this series is a task and time management application. Imagine you need to be able to enter tasks for individuals, track the time they spend on those tasks, link the tasks to customers and projects and so on. Obviously there are a lot of other systems and applications that support this kind of functionality, but this will make a good, easy to understand domain for the application we will build up.
In this article we will step through the following key concepts in WCF RIA Services:
- Project Links – A link between a Silverlight client project and a server web application or class library. The server project defines or references the domain services, entities, metadata, and shared code defined on the server side. As a result of the link, appropriate code is generated in the client project at compile time.
- Domain Services – This is the core construct of WCF RIA Services. A domain service defines the operations supported on the server side. These are usually mostly focused on CRUD operations against entity types, but can also be arbitrary operations to be invoked on the server from the client. These operations are exposed automatically via WCF and can be called from the client generated code without needing to know much at all about WCF.
- Entities – you define entitiy types on the server, and a client-side definition of the same entity type is generated for use on the client side. You can add validation and other kinds of metadata to the the entity definition which will affect the code generated on the client side, allowing you to just maintain a single server-side definition. The entity types on the client and server side are used to serialize and deserialize the data across the WCF service. The entity types can be created with Entity Framework, LINQ to SQL, or can be Plain Old CLR Objects (POCOs) that you define yourself.
- Domain Context – This is the client side counterpart to the domain service. It is generated code on the client side that gives you easy access to the functionality that resides on the server side. Internally it contains a WCF proxy that makes the service calls, and it also manages creating the queries that get executed on the server side, the change tracking for the entities being manipulated on the client and more.
- DomainDataSource – This is a data source object that can be used to execute queries and submit changes to the server side. It gets associated with the domain context and makes calls through that domain context on your behalf to query and update entities. It facilitate direct data binding from XAML or can be used behind the scenes as well.
Download the Sample Code.
Step 1: Create the Silverlight Application Project and Link to the Server Project
The application I’ll build in this series is based on a simple database that stores task and related entity information. To follow along with the steps, you will need to run the TaskManager.sql script in the download sample to create the database schema and populate it with a few sample entities. Once you have the database in place, you are ready to start creating the application. You’ll also need to have the Silverlight 4 Tools installed for Visual Studio 2010, which installs WCF RIA Services support as well.
Create a new Silverlight Application project named TasksManager. You can use WCF RIA Services with any of the Silverlight project types, including the Silverlight Business Application template that is added by WCF RIA Services itself. But to start simple, I’ll go with just the Silverlight Application template.
After you click OK in the new project window, you will be presented with the normal dialog to create a hosting web application project. What you will see that is new is a checkbox at the bottom to Enable WCF RIA Services. Check that box to create the link between the client project and the server project so that WCF RIA Services can code generate the appropriate client code based on the domain services and entities you will create.
Click OK and the projects will be created.
Step 2: Create the Domain Model Entities
WCF RIA Services is mostly about moving data back and forth between the client and server for you. So you need some data to work with. Out of the box, Entity Framework is supported best. With the WCF RIA Services Toolkit, there is also support for LINQ to SQL. And you can create your own domain services if you want to work with POCOs. For this article, you will use Entity Framework.
Right click on the TaskManager.Web server project in Solution Explorer and select Add > New Item, pick the Data category on the left, and select ADO.NET Entity Data Model, and name it TasksModel.edmx.
Click Add and you will see the Entity Data Model Wizard. In the first step, leave the option to Generate from database selected and click Next. Create a New Connection in the next step to the TaskManager database you created with the sample code SQL script at the beginning.
The connection name should default to TaskManagerEntities, which is fine. Click Next.
In the next step, Choose Your Database Objects, check the box for Tables to select all the tables and click Finish.
You now have an Entity Framework data model for all the tables in the database. In this article, you will only be working with the Task table, but in future articles in the series you will work with one or two other types.
Build the solution to make sure all is well. If you forget to build after adding your entity data model, it will not show up when creating the domain service in the next step.
Step 3: Define a Domain Service
So far, the only thing specific to WCF RIA Services you have done is check the box to create the link between the client and server project. Now you will do the core activity around RIA Services: define a domain service. Right click on the TaskManager.Web project and select Add > New Item. Select the Web category, and select Domain Service Class. Name the class TasksDomainService.
Next you will be presented with a dialog that lets you select a number of options for your service, including the most important option of what entities it will expose.
For this article, you will just be working with Tasks, so select that entity type and leave the rest of the defaults selected. I’ll be getting into more detail on some of the other options and what they do in other articles. Click OK and your domain service will be created.
Minus a bunch of comments they insert, the resulting class looks like this:
[EnableClientAccess()]
public class TasksDomainService : LinqToEntitiesDomainService<TaskManagerEntities>
{
public IQueryable<Task> GetTasks()
{
return this.ObjectContext.Tasks;
}
}
The LinqToEntitiesDomainService<T> class provides the glue between an entity data model and the services that will be exposed by WCF RIA Services. The EnableClientAccess attribute is what causes the client side code to be generated at compile time in the linked client project. From there, you add methods to your domain service to perform CRUD operations on the entities and possibly just expose operations that can be invoked from the client as well.
In this case, because you did not select the Enable Editing option in the previous dialog, the initial code only contains a single query method. I’ll get into more detail on the options and variations you have for query methods in the next article. But the one generated here uses convention to indicate that it is a query method based on the return type of IQueryable<T> and the method name. It just delegates to an instance of the entity data model ObjectContext that is created as a member by the base class and uses it to return all the Tasks. If you want to modify that query to order, filter, or page the results, as long as you return an IQueryable<T>, WCF RIA Services will be able to expose that as a service and generate the client code to consume it.
Rebuild the solution to make sure all is well and to generate the client side code. If you Show All Files in the TaskManager project, you will see a Generated_Code folder with a TaskManager.Web.g.cs file in it. This contains the generated code. I’ll dig into what is there in more detail in the next article.
Step 4: Retrieve Data into the UI with DomainDataSource
For this step, you will leverage the drag and drop capabilities of WCF RIA Services using hte DomainDataSource directly in the UI. In a later article I’ll discuss the MVVM pattern, why this is not the best architecture for complex applications, and how you can still leverage the DomainDataSource but do so behind the scenes in a local service.
For this article though, open MainPage.xaml in the TaskManager project. The designer will open. Open the Data Sources window (Data menu > Show Data Sources). It will take a moment the first time you open it after the client code generation, so be patient. But you should see entities for the types returned by the domain service listed in the Data Sources window.
Drag and drop the Task entity type onto the MainPage.xaml in the designer. A DataGrid will be generated with appropriate columns for each of the properties on the entity type, and a DomainDataSource will also be declared and hooked up to the GetTasksQuery method on the TasksDomainContext class. You can drop down in the XAML and remove all the sizing and positioning properties from the DataGrid (Height, Width, HorizontalAlignment,VerticalAlignment, and Margin) so that the DataGrid fills the containing Grid.
Build and run the application. You should see something like the following.
Summary
In this article, I covered the basic concepts behind a WCF RIA Services application and stepped you through the simplest possible WCF RIA Services application. You created an Entity Data Model, a RIA Services DomainService, and consumed that service in the client using the DomainDataSource and the generated TasksDomainContext. In the rest of the articles in this series, I’ll drill into more details on each aspect of WCF RIA Services, including real world application concerns of UI patterns, security, concurrency, testability, debugging and other aspects.
Download the Sample Code.
About the Author
Brian Noyes is Chief Architect of IDesign, a Microsoft Regional Director, and Connected System MVP. He is a frequent top rated speaker at conferences worldwide including Microsoft TechEd, DevConnections, DevTeach, and others. He is the author of Developing Applications with Windows Workflow Foundation, Smart Client Deployment with ClickOnce, and Data Binding in Windows Forms 2.0. Brian got started programming as a hobby while flying F-14 Tomcats in the U.S. Navy, later turning his passion for code into his current career. You can contact Brian through his blog at http://briannoyes.net.