Dan Wahlin (Microsoft MVP for ASP.NET and Silverlight) founded The Wahlin Group (www.TheWahlinGroup.com) which specializes in .NET, Silverlight and SharePoint consulting as well as online and onsite training solutions. Dan blogs at http://weblogs.asp.net/dwahlin.
Among the promises of frameworks such as Silverlight, Microsoft's plug-in for developing rich Internet applications, are lower development costs and shorter development cycles -- not to mention much more engaging and interactive Web content. But Silverlight also provides a broad range of networking features that can be used to access distributed data. Standard SOAP services such as those created using Active Server Methods Extension (ASMX) and Windows Communication Foundation (WCF) technologies can return a specific contract, and REST services can return custom data structures. Silverlight also supports direct socket communication for applications that require data to be pushed to them in real time.
While these features work well, there's a price in terms of complexity because they rely on an asynchronous programming model and require code to be synchronized between Silverlight and server projects. Microsoft recognized the challenges of the asynchronous model and that sharing data validation rules between projects could be tricky. To simplify the process, it has developed WCF RIA Services, a data exchange and validation framework for Visual Studio 2008 and Visual Studio 2010. Silverlight applications can also use WCF RIA Services to authenticate users, check roles, access profile provides, query and modify data and even share data annotations.
Getting Started with WCF RIA Services
Once WCF RIA Services is installed, new templates appear when you create a new Silverlight project as in Figure 1.
The Silverlight Business Application template builds on the standard Silverlight Navigation Application template, but adds authentication and WCF RIA Services support into the mix. The WCF RIA Services Class Library allows re-useable code to be encapsulated into a project that can be shared across one or more Silverlight projects. In this article I focus on the Silverlight Business Application Template.
To get started using WCF RIA Services you'll need to add a domain service class that wraps a LINQ-to-SQL or Entity Framework model into the Web project. It's important to note that other ORM frameworks such as nHibernate aren't supported out-of-the-box, but can be integrated into WCF RIA Services by deriving from a base class named DomainService and overriding the appropriate methods. Brad Abrams provides an introductory look at using nHibernate with WCF RIA Services at http://tinyurl.com/kmbkfl. Figure 3 shows a simple LINQ to SQL diagram added into the Web project that models tables in the Northwind database.
Once the ORM model is completed the project must be compiled so that the new objects are accessible to WCF RIA Services. After compiling, right-click on the project, select "Add --> New Item", then select the domain service Class template. The Add New Domain Service Class dialog window will appear which allows the desired DataContext or ObjectContext object to be selected (depending upon which Microsoft ORM was added into the project). The dialog window allows the entities that should be exposed by WCF RIA Services to be selected as well as whether or not the entities should support editing features (insert, update, delete). A metadata class can also be generated for each entity in cases where custom data annotations need to be applied for data validation. Figure 4 shows the Add New Domain Service Class dialog.
Once the domain service class is added into the project it can be customized. Listing 1 is an example of the methods added into a domain service class for the Customer entity in Figure 3.
[EnableClientAccess()]
public class NorthwindDomainService :
LinqToSqlDomainService<NorthwindDataContext>
{
public IQueryable<Customer> GetCustomers()
{
return this.DataContext.Customers;
}
public void InsertCustomer(Customer customer)
{
this.DataContext.Customers.InsertOnSubmit(customer);
}
public void UpdateCustomer(Customer currentCustomer)
{
this.DataContext.Customers.Attach(currentCustomer,
this.ChangeSet.GetOriginal(currentCustomer));
}
public void DeleteCustomer(Customer customer)
{
this.DataContext.Customers.Attach(customer);
this.DataContext.Customers.DeleteOnSubmit(customer);
}
}
A few things that are important to point out in the code shown in Listing 1 include the EnableClientAccess attribute which makes the class and its methods accessible to client applications such as Silverlight. Also note the IQueryable<Customer> type returned from the GetCustomers method. Any method returning IEnumerable<'T> or IQueryable<T> is treated as a query method by default in a domain service.
In situations where a single object needs to be returned as opposed to a collection the [Query] attribute can be used as shown next. This example sets the QueryAttribute's IsComposable property to false since the client won't need to perform query operations (sorting or filtering) on the returned object.
[Query(IsComposable=false)]
public Customer GetCustomer(string custID)
{
return this.DataContext.Customers.Where(c => c.CustomerID ==
custID).SingleOrDefault();
}
The other methods in Listing 1 automatically handle performing insert, update, and delete operations respectively due to their name being prefixed with Insert, Update or Delete. In situations where methods don't start with one of the built-in WCF RIA Services keywords, attributes can be applied above the methods as in Listing 2.
[Insert]
public void NewCustomer(Customer cust)
{
this.DataContext.Customers.InsertOnSubmit(cust);
}
[Update]
public void SaveCustomer(Customer currentCustomer)
{
this.DataContext.Customers.Attach(currentCustomer,
this.ChangeSet.GetOriginal(currentCustomer));
}
[Delete]
public void DestroyCustomer(Customer cust)
{
this.DataContext.Customers.Attach(cust);
this.DataContext.Customers.DeleteOnSubmit(cust);
}



