Sharing code between Silverlight and .NET

Currently, a Silverlight Class Library cannot be loaded by the server side project and vice versa. This despite there being very close parity in the BCL on either side. Now, I agree that sharing actual business logic between client and server is a bit of an edge case, but when it comes to data interchange, having a single codebase for you DTOs would be very useful.

Luckily, with a bit of trickery, this can be accomplished, although it would be nice if Visual Studio could just do this for you. I've done this on two different projects, once creating DTOs that were then serialized using the JSON DataContract serializer and other other time using the normal XmlSerializer.

The basic trick is this: Two separate projects can point at the same source code files (and even the integrated source control providers will play along with this game). However, playing by Visual studio rules you can't just create two projects in the same directory because the wizards treats ProjectName == DirectoryName. Here's how you get around this:

  1. Create a new server side Class Library, say Server.Dto.
  2. Create a new Silverlight Class Library, say Silverlight.Dto.
  3. Clean out that default Class.cs and update both to have the same default namespace Foo.Dto. Your solution should look something like this:
  4. Now, right-click on Silverlight.Dto and choose Remove
  5. Close Visual Studio
  6. Rename the Silverlight.Dto/Properties directory to Silverlight.Dto/Silverlight.Properties
  7. Copy Silverlight.Properties and Silverlight.Dto.csproj to the Server.Dto directory
  8. Now, and this is the tricky bit, open Silverlight.Dto.csproj in some text-editor (notepad works, but don't try to use Visual studio for this) and change the line

<Compile Include="Properties\\AssemblyInfo.cs" />
to
<Compile Include="Silverlight.Properties\\AssemblyInfo.cs" />

  1. Re-open your solution, right-click on the Solution in the Solution Explorer and choose Add -> Existing Project..., browse to Server.Dto and select Silverlight.Dto.csproj
  2. Add your first shared class FooDto.cs to Server.Dto (if you add it on the Silverlight side, you need to clean up a bunch of using statements).
  3. Select Silverlight.Dto and click the Show All Files button at the top of the panel. You should see FooDto.cs in Silverlight.Dto now
  4. Right-click FooDto.cs and choose Include in Project, like this:
  5. Voila, you now have two assemblies referencing the same code so that you can use the same code on both client and server sides. Just repeat the last couple of steps for every new class you want to share.

I know you could use a Web Service from within Silverlight and would automatically generate you the proxy on the client side. And I'd recommend that if your payload is dynamic. However, if your payload is generated occasionally by a server side program or periodic service, this methods lets you create Dto's, serialized in your favorite manner that can be consumed as static files with WebClient.