Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 13: The New Class Library Project

Well… this has been one of the longer blog series I have done, but there is so much meat here!  Maybe someone will write a book or two?  Anyway, in this post, I wanted to spend a little time looking at the project structure we have been working with and see if there is a way to improve it a bit with more clear separation of concerns. 

For those of you just joining it, this is yet more updates to my Mix09 talk “building business applications with Silverlight 3”. You can watch the original  video of the full session

The demo requires (all 100% free and always free):

  1. VS2008 SP1 (Which includes Sql Express 2008)
  2. Silverlight 3 RTM
  3. .NET RIA Services July '09 Preview

Also, download the full demo files

The core project structure we have been using so far is a single solution with two projects in it:

MyApp – The Silverlight App

MyApp.Web – the web application

The MyApp.Web project actually has two very distinct concerns.. the first is handing the AppLogic for the entire app, the 2nd is the web and services interfaces (specifically the default.aspx down level rendering, sitemap.aspx and SuperEmployeeService.svc).   Two concerns in the same project bother me at some level as I tend to like a cleaner separation for maintenance and better cross team work.  Luckily, new in the July update to RIA Services is a new RIA Services Class Library project.  We will look at refactoring the MyApp.Web project to pull out the appLogic concerns into a separate project. 

Right click on the solution and select “Add New Project….”

image

This creates a pair of class library projects.. one for the client and one for the server. 

image

First you will need to add a reference from the MyApp.Web project to the SuperEmployeeRIAServicesLibrary.Web.. We are going to want to access the DomainService defined in this library from several places in the WebApp. 

Now, simply add an Entity Framework model and SuperEmployeeDomainService to the SuperEmployeeRIAServicesLibrary.Web project exactly as we way back in step 2.  Once you have the SuperEmployeeDomainService class created, you can copy over the implementations we did thus far… remember to grab the cool metadata validation attributes as well.

Then you can delete the Domain services classes from the MyApp.Web project.  This gives you a very clean set of concerns..

image

Notice that SuperEmployeesRIAServicesLibrary.Web contains the datamodel and Domain classes and the MyApp.Web project has the asp.net pages and the service.  All that access the DomainModel from the class library project.

Notice if you are using the “Business Application Template” as I am in this walk through, you will notice a Services folder that includes some DomainServices for dealing with user management.   In some ways, I think of this as an application wide concern, so it might make sense to leave these in the web project, but if you’d like to move them, no problem.  Just add the following steps:

1. Move the entire directly to the SuperEmployeeRIAServicesLibrary.Web project.  It is likely a bit cleaner to update the namespaces in these types, if you do so, you will need to update the namespaces on the client as well.

2. Break the “RIA Services Link” from the Silverlight client to the MyApp.Web project in the MyApp properties page.
image

3.  Add a project reference from MyApp to SuperEmployeesRIAServicesLibrary

4.  Add a simple RIAContext class to your application

 public sealed partial class RiaContext : System.Windows.Ria.RiaContextBase
 {
     partial void OnCreated();
  
     public RiaContext()
     {
         this.OnCreated();
     }
     public new static RiaContext Current
     {
         get
         {
             return ((RiaContext)(System.Windows.Ria.RiaContextBase.Current));
         }
     }
     
     public new User User
     {
         get
         {
             return ((User)(base.User));
         }
     }
 }

 

 

5.  Explicitly wire up the AuthDomainContext in App.xaml.cs with lines 5 and 6.

    1: private void Application_Startup(object sender, StartupEventArgs e)
    2: {
    3:     this.Resources.Add("RiaContext", RiaContext.Current);
    4:  
    5:     var auth = RiaContext.Current.Authentication as FormsAuthentication;
    6:     auth.DomainContext = new AuthenticationContext();
    7:     
    8:     this.RootVisual = new MainPage();
    9: }

Again, the above steps are optional – only if you want to factor out the DomainService completely from your web application.

Now we just need to update some namespace references across the silverlight client and the web because our DomainService class is in a new namespace.  And presto!  The apps works great, but now the project is better factored for long term maintenance.

Notice that every aspect of the app keeps working…. 

The Silverlight client..

image

The ASP.NET view (for SEO)..

image

The Service…

image

And of course the WinForms client for that service..

image

Comments

  • Anonymous
    July 28, 2009
    So Brad, let my clarify this: a) Your new RIAServiceLibrary.Web is referencing the old MyApp.Web? b) And your SL Client is Referencing the new RIAServiceLibrary (client dll)? c) And what happens after you break the link “RIA Services Link” from the Silverlight client to the MyApp.Web project? Do you leave it broken? d) I think it would be great if the "Business Template" would do this automatically! Brad, this whole series have been very helpful, but this was something I needed now :-) The RIA docs is very brief on this sunject. Thanks! ..Ben

  • Anonymous
    July 28, 2009
    This is a great post for Silver light application. I am looking forward for your upcoming posts. Good Work Singh

  • Anonymous
    July 28, 2009
    Brad, I have encountered the following errors:

  1. When using EF DAL, if I add an association I get a compile error that the association cannot be found when generating the client side code.
  2. When using LTS with a DomainService I get compile errors that all the entities are defined multiple times when generating client side code. Also, an example of using the DomainContext.Load method with callback methode would be usefull. Thanks for this great series.
  • Anonymous
    July 29, 2009
    Brad, never mind on my (a) question. So, basically the SL Client (MyApp) reference the new RIA Service client and the SL web section (MyApp.Web) references the new RIA Service Web. But I'm still puzzled about the Link breakage. Could you also explain the addition of RIAContext class. Thanks! ..Ben

  • Anonymous
    July 29, 2009
    Part 13? Where's the first part?

  • Anonymous
    July 29, 2009
    Chris -- wow, the series has gotten long if you can't even see the first one ;-)   Try this: http://blogs.msdn.com/brada/archive/tags/RIAServices/default.aspx

  • Anonymous
    July 29, 2009
    OK, so I've followed this through and done exactly as you've said, but as soon as I load the application my datagrid is empty and the Activity doesn't even show.  Any ideas as to why this might happen?

  • Anonymous
    August 03, 2009
    Great, I suppose this will make integrating with Prism much easier!

  • Anonymous
    August 22, 2009
    Hopefully I can save someone else some pain :) If you are following along with this series, the above will work just fine.  HOWEVER if you never built this app with a combined library, but rather created it from scratch with a split RIA services library then remember this... YOU MUST COPY THE CONNECTION STRING from the Services library projects App.Config to the .Web projects Web.Config. I feel like such a newb :) Ken

  • Anonymous
    August 22, 2009
    Soulhuntre  - thanks for the tip!  This is a very important point... sorry I did not make that clear in the flow.

  • Anonymous
    October 17, 2009
    Hi. "YOU MUST COPY THE CONNECTION STRING from the Services library projects App.Config to the .Web projects Web.Config" . - it's there a way to provide this connectionString dynamically. The main idea is:  - I want to dynamically deploy service (RIAServiceLibrary.Web modules) into my running application.  The only problems is this connection string - I don't want to manual add them in web.config file.   Thanks! Radu