27 January 2012

WCF RIA Services Learning Notes

Why bother with RIA Services?

Because Lightswitch is awesome! Out of the box I can connect to SharePoint lists (no attachment support in v.1) and to SQL Server. For anything else, I’ll need a custom WCF RIA Service. By anything else, I mean (for now) Dynamics CRM.

I plan to write some more on Lightswitch later on, to document my learning as much as anything. One use case I see for Lightswitch is for creating those applications for which one or two people need a different set of screens to more efficiently work with existing data. In many of these cases, there may be insufficient return (or available developer time) to warrant extensive custom development.

My own interest then is to create a stand alone RIA Service, probably wrapping an existing WCF Service (such as those that ship with Dynamics CRM 2011 or SharePoint 2010), stored procedure or other code.

The following notes are mainly for myself – I’ll probably need to find them again some day soon. Neither of the other two people who might read this blog are likely to ever care… Winking smile

Visual Studio will allow me to “Enable WCF RIA Services” when I create a Silverlight application. My problem with doing this is that like the WCF project templates, it hides so much of what’s going on and also commits me to creating a Silverlight application anyway. It’s not really what I want to do. I guessed the process is worth doing once, so I followed the “Walkthrough: Creating a RIA Services Solution” from MSDN. But any goose can click through a wizard and I’m afraid I can’t say I’m much the wiser for it.

The following is my post-mortem from working through the walkthroughs and how-tos on MSDN for WCF RIA Services.

Walkthrough: Creating a RIA Services Solution

(Source) I found that this walkthrough left me with more questions than answers. Because so much was automatically created and everything was pretty much thrown together, I didn’t know what pieces were what and more importantly which pieces mattered when building a custom RIA Service for use by Lightswitch (or JavaScript).

How-to: Create a Domain Service that uses POCO-defined Entities

(Source) This was a useful walkthrough though it has an error. It was a useful learning experience.

Building the solution according to the steps led to code like the following :

[EnableClientAccess()]
public class SovereignDomainService :
DomainService
{
}

public class
Sovereign
{
    [Key]
    public int UniqueId { get; set; }
    public string Name { get; set; }
    public string House { get; set; }
    public string Dominion { get; set; }
    public int ReignStart { get; set; }
    public int ReignEnd { get; set; }
    public string Sobriquet { get; set; }

    public List<Sovereign> FetchSovereigns()
    {
        List<Sovereign> sovereignList = new List<Sovereign>
        {
            new Sovereign()
            {
                UniqueId=1,
                Name="John",
                House="Plantagenet",
                Dominion="Angevin Empire",
                ReignStart=1167,
                ReignEnd=1216,
                Sobriquet=
"Lackland"
           
},
            new Sovereign()
            {
              
// ... Abbreviated for space...
           
}
        };
        return sovereignList;
    }

    public IEnumerable<Sovereign> GetSovereigns()
    {
        Sovereign sovereign = new Sovereign();
        return sovereign.FetchSovereigns();
    }

    public IEnumerable<Sovereign> GetSovereignsByReignEnd(int ReignedBefore)
    {
        Sovereign sovereign = new Sovereign();
        return sovereign.FetchSovereigns().Where<Sovereign>(p => p.ReignEnd <= 1500);
    }
}

Generating this, produced an empty code gen file (RIAServicesExample.Web.g.cs) in the client project.

The correct version puts the three methods inside the SovereignDomainService class. The two GetX methods call FetchSovereigns. When built, this produces a considerable amount of generated code. I certainly wouldn’t want to generate this by hand. The Sovereign class gets transformed and marked with the WCF DataContract attribute, also inheriting from System.ServiceModel.DomainServices.Client.Entity, and the properties get transformed and marked with the WCF DataMember attribute.

The SovereignDomainService is transformed into a partial sealed class. This provides the extension mechanism – as the code I’m viewing is generated, I can’t change it as any changes would be smashed next time I build the project. The constructor creates the SVC file.

An interface for the SovereignDomainService is created as an inner interface. It’s fully qualified name in this example is RiaServicesExample.Web.SovereignDomainContext.ISovereignDomainContext. I’ve never seen one before, though I’d say this follows the same rules as an inner class. Namespaces for the FaultContract and OperationContract types are for tempuri.org. I want to find out how to change this.

Walkthrough: Creating a RIA Services Class Library

(Source) I found this walkthrough to be a good next step from the previous how-to. In this walkthrough, I created a Silverlight project (without WCF RIA Services enabled) and a separate WCF RIA Services Class Library project. This project template is found under the Silverlight section. I’m not convinced this is a good decision as WCF RIA Services can also be built for JSON (JavaScript) clients – it’s just a matter of configuration.

Following this walkthrough, I end up with four projects (from the two project templates). The RIA Services Class Library contains the Entity Data Model, while the Silverlight.Web project contains a reference to the RIA Services Class Library Web project.

There are a few manual steps here that aren’t present in cases where you tick “Enable WCF RIA Services” in the New Silverlight Application wizard when you create a new Silverlight project but it’s no big deal. It mainly boils down to adding a few DLL references and modifying your web.config with values that were automatically created in the WCF RIA Services Class Library project – it comes down to a bit of copy/paste.

Summary so far…

Being able to build custom WCF RIA Services are essential for assembling Lightswitch applications that connect to data sources other than SharePoint 2010 lists and SQL Server databases. In cases where you’re not meant to access the database directly (eg. Dynamics CRM), for re-using existing business logic and for accessing other types of data (eg. XML or NOSQL data), you’re going to have to build a custom WCF RIA Service.

I’m not sure whether I have a similar business case for JavaScript clients. I may be better off using JSON / XML directly. I imagine though that if the RIA Service is already built than it looks like I have everything built that I will need, leaving only the necessary configuration to emit JSON data.

2 comments:

  1. Hello, Mike

    Were you able to deploy your project ? I recently also followed the MSDN (Walkthrough: Creating a RIA Services Class Library), but I was having trouble deploy it to the server. I was able to access the WCF, but I couldn't get around changing my SilverLight to connect to it. I tried to connect to it from my VS project as WCF service, but it kept saying it was not able to find any datacontract on it.

    I would like to keep the WCF and SilverLight as separate instead of as one solution. And use the SilverLight as a web resource in CRM.

    ReplyDelete
  2. Hi! Thanks for finding my blog and for leaving a comment.

    I did this 6 months ago now (wow - time is flying by) and it's a little difficult to be sure what happened now. I had a look at it today and I can say that I did only use F5 from Visual Studio. I didn't deploy to IIS, which is what I think you want to do. I'm not much of a Silverlight developer so can't say what has to happen there or what the moving parts are.

    I'm not sure what changes you want to make in your Silverlight that you are referring to either. Are you splitting your XAP file from the RIA Service and trying to host it in a separate IIS application from the RIA service?

    In any case, it's a worthwhile next step that I haven't followed through on. I plan to have a closer look at it over the weekend. I'll post again with what happens as I'll probably need it again one day... ;-)

    Thanks again for getting in touch.

    Cheers
    Mike

    ReplyDelete