WCF RIA Services Overview

WCF RIA Services makes it easy to concentrate on the data and business logic rather than worrying about creating multiple layers. Besides that it also simplifies querying, updating, validation and authentication among other features.

Design Pattern
  • WCF RIA service design pattern has three main aspects. These reside between the DAL and UI Views.
    • Data Model - After the DAL is set up, RIA creates entity and metadata on the server side and entity proxies and metadata on the client side. A metadata file is added on the server side allows us to add, besides other things, validation rules to the entities.
    • DomainService - on the server side. Provides a way to add CRUD and custom logic. RIA architecture defines a stateless server.
    • DomainContext - on the client side. Provides a way to add methods to load and invoke server side functionalities. RIA architecture defines a stateful structure. This is to enable data caching on the client side.
    • EntityContainer - on the client side. To hold the entities since client is stateful. EntityContainer enables the client side data caching.
    • Most of the client side stuff is added automatically when we add server side items and build the solution.
Steps to get up and running
  • Create simple Silverlight application and enable WCF RIA services
  • Add your DAL (through Entity Framework or LINQ to SQL etc)
  • Add DomainService on the server side. 
  • Build the solution
  • Build adds a DomainContext and entity structure with metadata on the client side. 
  • Use this DomainContext to create queries. Queries are of type EntityQuery.
  • The service is located at http://localhost:xxxx/services/<appname>-web-<domainservicename>.svc
Updating/Retrieving Data
  • To update data, use the DomainContext's SubmitChanges(), RejectChanges() methods.
  • To retrieve data, use the DomainContext's Load method to load queries.
  • Load method provides an important option called LoadBehavior which is explained further below.
Validation
  • For validation, it provides attributes such as Required, Range etc which can be put on data entities on the server side and they will propagate to the client side.
Query operations on the domain service
  • Queries in the Domain service follow some simple rules based on WCF, such as, they can return/take only primitive types. There can not be any overloads. These functions need to be public etc.
  • If needed, we can decorate these functions in domain service by Query attribute. It provides us options to further constrain the results. For ex.
    • IsComposable - if set to false, doesn't allow the client to put any more filtering on the client side. The query has to be used as it is and no further composition is possible.
    • ResultLimit - to limit the no. of instances that can be retrieved from the server.
    • HasSideEffects - to indicate that the query should be invoked via HTTP Post. HTTP Get is the default.
Asynchronous Loading
  • Calls from client are asynchronous so that the UI is not stuck. The callbacks can be implemented using various ways.
  • As soon as the client call is made, the function returns a LoadOperation object.
  • We can handle the callback by providing a LoadOperation.Completed event or providing a lambda expression/delegate inline.
Client Side Data Caching
  • Once some data is loaded on client side, its cached by the Domain Context to improve performance.
  • Since data is cached, RIA provides a way to handle scenarios where the data on server side has changed. This is done by the LoadBehavior enum of the Load method. It has 3 options -
    • KeepCurrent - objects in the client cache are kept as it is. This is default.
    • RefreshCurrent - objects in the client cache are replaced by the objects on the server side when load is called.
    • MergeIntoCurrent - only updates the objects that have not been modified since the last time the cache was loaded. So all the client side objects which were modified remain the same. All client side unmodified objects are refreshed from the server.

No comments: