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