Tutorial for Configuring Silverlight 4, Entity Framework and WCF RIA Services in Separate Component Assemblies (DLL’s)
Why does Microsoft assume that we want to combine our business, data access, service, and web layers together in a single web project? Without sounding too much like a rant here, take a look at almost ALL of Brad Abrams (former Microsoft Architect for WCF RIA Services and Entity Framework) posted examples of how to use the Entity Framework with RIA Services. They all have the Entities, RIA Services, and pretty much all of the other data logic included in the Web Application project.
Obviously, this does not promote re-use of the single most shared component in most enterprise companies systems, the Data Access Layer (DAL). Not many are going to need to reuse the domain services generated for a project because they are going to have a lot of hard-coded logic that is specific to an application (maybe that is debatable because you could design this for a lot of reuse) but many applications access the same database and having to rebuild the same model, maintain it in multiple projects, and any customizations and validation you add very problematic. Since the inclusion of the great visual designer tools in the first version of ASP.NET, Microsoft has been on this path of tightly coupled, small project coding that makes reusing something as a component/assembly/DLL in another project difficult if not impossible.
Silverlight Issues with Coupled Components
Unfortunately, this trend is continuing with the amazing Silverlight/RIA Services/Entity Framework stack which is really awesome. I can’t say enough great things about it but I really have to take issue with the assumption about tight coupling. Yes, if your project is small and you have a small database and you are only one of a few developers and work on a single product (BTW: This is probably the majority of software projects so that is why they have focused on this), then this solution works great. If you have multiple products that access the same database, have to create API/Web service access to your systems, have to share code with 100’s of developers, or need to reuse components and libraries across lots of projects, then you will be left scratching your head on examples. The same thing for how Microsoft is showing examples for Silverlight applications.
So here we have put together a tutorial for how to create a project with your DAL, RIA Services, Web project, and Silverlight components all in separate assemblies. These assemblies are reusable and can be shared across applications. This also has the nice benefit of organizing the code and keeping every assembly focused on a single capability.
Project Structure
I want to say a few things about project structure and naming with Visual Studio 2010. Here is a screenshot of the project structure:

Although not specific to implementation, we use a naming convention where we preface project/namespaces for Silverlight assemblies and web applications with “client” and assemblies and web projects that are specific to be run on the server are prefaced with “server”. I know, I know, there are already icons for these types of projects to help differentiate them but the icons are so small and look so similar to it hard to track. Also, it is nice to have a namespace that tells you in the code where a particular object or component maps to.
Description of Project Structure
The projects listed here are as follows:
EntityComponentTest.Client.Data – This is a stub for the data access layer on the Silverlight side. This assembly interacts directly with the server’s Entity Framework DAL layer.
EntityComponentTest.Client.WebApp – This is the Silverlight web application where the XAP is compiled into. This contains App.xaml and MainPage.xaml.
EntityComponentTest.Server.Data – The DAL for the application. This is where the Entity .edmx files are located.
EntityComponentTest.Server.Service – This is where the WCF RIA Services which use the Entity Framework objects to pass data to and from the database to the Silverlight client.
EntityComponentTest.Server.Web – The web project where the pages that host the Silverlight XAP are hosted.
Creating the Projects
Here are the basic steps to get this all working. Once you’ve created your solution to hold these projects, first add the server-side projects.
NOTE: To get this to work right, you need to make sure all the tools for Silverlight including the RIA services toolkit are installed on your development machine. You can get the tools here: http://www.silverlight.net/getstarted/
Create a new ASP.NET web project and name it according to your naming standard. This will be where the Silverlight XAP is hosted. (EntityComponentTest.Server.Web)

Create a new Class Library for the DAL layer. This is where your Entity Model (edmx) will be placed. (EntityComponentTest.Server.Data)

Create a new Class Library for the WCF Services. This is where your WCF RIA services will be placed. (EntityComponentTest.Server.Service)

Create a new Silverlight Class Library for the DAL stub on the client side. Make sure this is a Silverlight assembly. (EntityComponentTest.Client.Data)

Create a new Silverlight Application. This is the main app that will be packaged in your XAP for the logic of your Silverlight application. NOTE: When you do this, the system will probably ask you if you want to associate this project with your web application. Say yes, and let it create a page for you and hook it all up. (If you forget to say yes here, it is easy in the web project properties to set the Silverlight application later).

Setting References
Set a reference from the EntityComponentTest.Server.Web project to the EntityComponentTest.Server.Service project.
Set a reference from the EntityComponentTest.Server.Service project to the EntityComponentTest.Server.Data project.
Set a reference from the EntityComponentTest.Client.WebApp project to the EntityComponentTest.Client.Data project.
Configure Settings to get WCF RIA Services to talk to Silverlight
A few settings need to be configured in order to get the WCF RIA Services to show up in the Silverlight application. Right click the EntityComponentTest.Client.Data project and choose “Properties” from the context menu. Set the properties on the Silverlight tab for the WCF RIA Services Link to the EntityComponentTest.Server.Web project similar to this screenshot.

Now edit the Web.Config in the EntityComponentTest.Server.Web project so that the services will be able to be served by the web project (basically handles custom pathing for service URL’s and importing the System.Data.Entity assembly. Add this element to the Assemblies section:
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
Add this element to the httpModules section:
<add name="DomainServiceModule" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
Add this element to the System.ServiceModel section:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
Your web.config will look similar to this:

Setting up the Entity Model
Now in the EntityComponentTest.Server.Data project add an ADO.NET Entity Data Model (edmx) file to store your data model.

I have created a simple database table to illustrate the process called “Customer”. Here is a view of what the table schema looks like in SQL Server.

Now connect your entity model to your database and add this customer table to your edmx model. Your model should look like this when you are done.

Setting up the WCF RIA Service
Now we can create a WCF RIA Service to access this table to do selects, inserts, updates, and deletes from the Silverlight client. But MS has made this harder than it should be to get it to work in your loosely coupled project. You have to do a little trickery to get this to work.
NOTE: The reason for this is that the “service.metatadata.cs” files that are auto-generated when the service is added for its Entity model(s) MUST be in the same assembly as the Entity Model (edmx) itself. This is a hard and fast rule. But we don’t want our services (web access layer) in the same assembly as our data model (what if we want to use our DAL layer somewhere else and don’t want to expose it through RIA services?).
To get around this, we first add a Domain Service Class to our EntityComponentTest.Server.Data project first.

This will create the metadata.cs file(s) in the correct place and set your services up right. Then move the newly created “service class” (DevToolShedService.cs in this example) to the EntityComponentTest.Server.Service. Then to get this to fully work in your service assembly, you need to change the namespace for both the DevToolShedService.cs and DevToolShedService.metadata.cs classes to point to the EntityComponentTest.Server.Service. So your Service class should look like this at the top when you are done.

Testing the Application and WCF RIA Services
To test the application, go the MainPage.xaml in the EntityComponentTest.Client.WebApp and add a DataGrid so we can show the list of Customers from our Customer table. You XAML should look something like this:
<UserControl x:Class="EntityComponentTest.Client.WebApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <sdk:DataGrid Name="dgTest" AutoGenerateColumns="True" Height="500" Width="500" HorizontalAlignment="Left" VerticalAlignment="Top" /> </Grid> </UserControl>
Now in the MainPage.xaml.cs code behind, we can bind our Customer data to the grid with code similar to this:
namespace EntityComponentTest.Client.WebApp { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); this.Loaded += new RoutedEventHandler(MainPage_Loaded); } void MainPage_Loaded(object sender, RoutedEventArgs e) { // create a context to the WCF RIA service and call the RIA service method // to get the list of all customers. var context = new Server.Service.DevToolShedContext(); dgTest.ItemsSource = context.Customers; context.Load(context.GetCustomersQuery()); } } }
Now run your project and you should see a list of customer data from your Customer table working and everything is decoupled (as much as we can in Silverlight) and this makes it easy to re-use your data access layer in other projects without having to bring all your exposed RIA services with it.
You can download the solution and project files for this project here:
Popular Articles
Recent comments
- Aha! Problems with UpdatePanel? Sorted ...
18 hours 1 min ago - Some help required with this
23 hours 35 min ago - Never seen this issue
1 week 1 day ago - Error in query.ToList()
1 week 1 day ago - Thanks
1 week 2 days ago - Thanks
1 week 5 days ago - To get the data working,
2 weeks 19 hours ago - If I manually change the
2 weeks 20 hours ago - Handling EDM Relationship Metadata
2 weeks 20 hours ago - About the itextsharp version
2 weeks 23 hours ago


Handling EDM Relationship Metadata
I am trying to make your design work. It has great promise; however, if EdmRelationshipAttributes are created by the model, how do I reference the various types (EntityComponentTest.Server.Data) within the model from the altered designer.cs (namespace of EntityComponentTest.Server.Service)?
Thanks!
If I manually change the
If I manually change the references to the entities within the block from EntityComponentTest.Server.Data.EntityName to EntityComponentTest.Server.Server.EntityName, then the code builds fine. I'll have to remember to change these if the model is regenerated (well, the compiler will remind me, I'm sure).
I still do not have data populating my grid, though. Hopefully, I'll see what piece of the puzzle I have missing and get this working. I like the structure. Thanks for posting it!
To get the data working,
To get the data working, simply copy the connectionStrings from the app.config of the Server.Data project to the web.config of the Server.Web project. All is good.
More in deep explanation
Thanks for this document. There is not enought about this subject. Great tutorial.
Just some question at respect:
Do i understood?, BLL is still coupled with DAL cuz them are in the same namespace (service), but the benefice of implement that in separate dll´s is that them are independient?
In this aspect DAL yet knows about BLL ?
Thanks in advance, great
Can't get the tutorial code to work as demonstrated.
I've run through your demo 3 times now, and ran into the following problems:
1) The namespace needs to be changed to (Project).Server.Service for the xxxxModel.Designer.cs as well as the metadata, and DomainService files. This is a problem if you make changes to the Domain and it automatically overwrites the file for you constantly.
2) Replicating your example, the Context doesn't get passed correctly through to the .Client.WebApp silverlight app. I keep getting the error Cannot implicitly convert ObjectSet to IEnumerable.
3) The Service application needs references to the System.ServiceModel.DomainServices.EntityFramework (everything added when adding a Domain Service)
4) After all this Silverlight still can't find the correct Context using projection.
So maybe I'm making a big dumb mistake, but this seems to make the separation even more difficult, if you have to rewrite the namespace of the EntityFramework cs file right?
Looks really promising, but leaving those aspects out make it hard to be usable - although your code example works - which contains all the changes above + something I can't find.
Any advice is appreciated. Tks
Sorry to hear your trouble
Man, that is a big bummer. Here is what I can tell you. I did this step by step on my machine and took screenshots of everything as was able to complete it successfully. Many others have emailed me and said they successfully followed these instructions and were able to get it working from the tutorial.
In addition, you can download the exact project I created with all of the code so you could go through in detail and see if any properties or settings or DLL versions are different to help you troubleshoot.
It could be you are running a different version of Entity Framework or RIA than I had installed as well.
For issue one with the namespaces, yes, if you change the domain, you will have to recopy the files. I wish MS would fix this!
Issue 2, I am not sure why you are getting the IEnumerable error. Not enough info there for me to tell.
Issue 3, the service does need a reference but when I did this, it was automatically added by VS 2010.
Issue 4, if Silverlight can't find the context, then it can be one of many reasons but a likely issue could be that you are not targetting the correct RIA assembly in the properties of your Silverlight app.
I think I figured it out.
You're not supposed to do it this way. Try with a Ria Services project first --
http://blogs.infosupport.com/blogs/willemm/archive/2010/06/01/creating-m...
heh
tks for the reply
Enumerable: Yeah that's still the issue, and I'm pretty sure its RIA related. I can see it working in your demo project - and yet every time I recreate it, I get the same error. Any idea on paths to troubleshoot? (I did install RIA just last week so I don't know if that's part of the issue)
Scouring all the differences between your working code and the project I developed was how I found that the domain objects were set to Server.Service. Now I also know its generated with a t4 somewhere - if it just gave us access to that t4 then we could adjust it!
About the References:
Well - the service gets its references when you add it to the .Server.Data project, but then when you move it - it doesn't have them anymore. I ended up just creating a blank service and deleting it - which recreated those references. It was just missing from your example is all, only reason I mentioned it.
Again any help on troubleshooting why RIA isn't projecting correctly would be appreciated. Thank you!
What's the point
I'm missing the point here.
The eventual purpose of your solution is to have a DAL which can be potentialy reused for other purposes. Nonetheless, the 'tricks' with the namespaces cause that your DAL is already semantically linked to the service layer (since the DAL assembly contains the namespace EntityComponentTest.Server.Service).
Correct me if I'm wrong but I don't see any added value. Did you try also custom validations in this configuration?
Kind regards
paul.
De-coupling the DAL
It is true that the service layer does have a tight dependency on the DAL layer and yes, you are right, the DAL cannot be removed in this scenario
BUT
the DAL does not have a dependency on the service layer so it is free to be copied or referenced by other projects and reused. This is the big benefit, reuse of the DAL layer.
So far in my experience, there haven't been many (if any) occasions where I've wanted to reuse the RIA services only because they are usually coded totally specific for a particular project whereas the database and the DAL are not coupled here and can be resued elsewhere.
DevToolShedModel.Designer.cs - Namespace ?
Hi,
Thank you for these valuable informations.
I've a simple question(maybe i'm wrong ?)
When you create the EDMX in the EntityComponentTest.Server.Data project, the namespace of DevToolShedModel.Designer.cs is set to 'EntityComponentTest.Server.Data'.
Thus, trying to move the metadata file to 'EntityComponentTest.Server.Service' Namespace, will failed.
Looking at your sample, I've seen that the DevToolShedModel.Designer.cs is in 'EntityComponentTest.Server.Service' Namespace.
Have you moved the namespace ? Is this point missing in the tutorial ?
Thanks again for the job.
Compile error with SL4 business app template
Thank you very much for this information, it's really needed! Anyway, I have tried a variation with a VS2010 Silverlight Business application together with its website (e.g. MyApp and MyApp.Web). Everything works fine until in the client.data project I add the WCF RIA services link to MyApp.Web: at this point, I get 5 errors like 'The type or namespace name 'Resources' does not exist in the namespace MyApp.Web' (are you missing an assembly reference?). If I remove the link the application builds fine again. Could you give a hint for using your tutorial with such applications?
Thanks!
Compile error with SL4 business app template
Right, you just need to "include" the Resource files in your SL Class Library (Client.Data).
1.) Create a folder structure in the Client.Data project for the server-side resources. In my case I made it: {ProjectRoot}\Server\Resources.
2.) Now, right click the new "Resources" folder you just created and choose "Add --> Existing Item...".
3.) Browse to your Web solution that is hosting the SL app (Server.Web) and browse down through until your find the Resources folder within it (usually it's just at the root).
4.) Now, select the resource files you need, however, don't forget that instead of clicking the "Add" button, click the drop-down arrow on the "Add" button and choose "Add as Link". In my case, I just needed to add "ErrorResources.Designer.cs" and "RegistrationDataResources.Designer.cs".
That should be it, now your projects will compile.
Possible solution
Without seeing exactly what you code and project set is like, my hunch is that in the case of a business application, you may need to set your WCF RIA Services link to your MyApp.Data server-side DAL layer assembly instead of your web. Also, another idea is to make sure your MyApp.Web has a reference to your MyApp.Services assembly where your RIA services are.
Can you expand this just a little?
I am very new to silverlight and using web services.
Now that I have followed your article and published the web service piece to the server (and moved that pesky app.config connection string to web.config and changed the namespace in that model.designer.cs) everything works swell!!
However, how do I write a brand new Silverlight application that reuses that service? I've seen examples of exposing the RIA Service as WCF/WSDL or OData services, but nothing that allows me to reuse a RIA Service as a RIA Service.
Please help.
Thanks
Exposing RIA Services to another Silverlight App
This should be relatively easy. Just add another silverlight app to your solution and then follow the steps above to set its references and configuration the same as your other Silverlight application. Then it should run just the same and be able to use the same RIA services layer assemblies.
صور
Thank you very much for this valuable information صور
العاب
It's really an excellent program and a comprehensive العاب
Awesome
I was horrified to find that all the RIA services examples forced you to create a tightly-couple web app structure. Your article is what I wanted to find in the first place from Microsoft. Well done!