Sharing Code Between .NET and Silverlight Platforms

Quite often, I hear people asking if they can use .NET assemblies compiled for the full .NET runtime in Silverlight.  Unfortunately, this just isn’t possible, the Silverlight runtime is a subset of the full .NET runtime and for code to run correctly under the Silverlight runtime, there are various dependencies that must be linked and verified at compile time.  But (there is always a but), there is one technique that you can use that effectively allows you to write your code once and have it work in both Silverlight and regular .NET applications.  This isn’t a new technique, but I’m often surprised when people tell me they haven’t ever seen it.  Let’s get a few basics out of the way first.  If you already understand the concepts of Linked Items and Solution Folders in Visual Studio, you can safely skip to the section entitled Sharing Code Between Platforms.

Linked Items
Linked Items are a little-known feature in Visual Studio.  Basically, Linked Items allow you to share a single file between multiple projects.  The best analogy for Linked Items is when you create a shortcut to a file in Windows.  You can have any number of shortcuts to a particular file, but ultimately, they all open the same file.  Creating a Linked Item is simple:

Step 1:  Right-click on your project in the Solution Explorer and click Add –> Existing Item …

image

Step 2: Select the file you wish to share and select ‘Add As Link’ on the Add button.

 

image

The linked file will look like a shortcut item in your project.

image 


Solution Folders 
To make your shared code more visible and your solution structure more understandable, you can add a solution folder and place the actual file here.  Solution Folders are really just organizational mechanisms in Visual Studio.  You can place just about anything you like in these folders, including projects.  I often use Solution Folders to group similar projects together.  To create a solution folder perform the following steps:

Step 1:  Select the solution in your Solution Explorer and click the ‘Add New Solution Folder’ icon.

 image

Step 2: Give the folder a good name.  In this example, I am calling the Solution Folder: Shared Code.

image

Step 3: Now, add the actual file to the solution folder.  Keep in mind that these solution folders are virtual, they do not necessarily correspond to actual folders on the file system (although it makes things easier if they do).

image 


Sharing Code Between Platforms
In the scenario below, we have a solution with a regular .NET Class Library and a Silverlight Class library.  We are sharing the Utilities.cs file between the two projects using Linked Items and we have included the actual Utilities.cs file in a solution folder called ‘Shared Code’.  When we build the solution, each project will use the Utilities.cs file and the logic contained within will become a part of each assembly.  This is an excellent application of the DRY principle.

image 

Conditionally Compiling Code
Inevitably, you will have code that simply does not port correctly between full-blown .NET and Silverlight.  In cases like these, you need to make the compiler conditionally compile parts of your code.  You can do this very easily with something called Conditional Compilation Symbols.

If you right click on your Silverlight project in the Solution Explorer, click Properties, and then click the Build Tab you will see the following:

image

Notice, for the Silverlight project, conditional compilation symbol called SILVERLIGHT is defined.  With this symbol, you can use conditional compilation directives to have the compiler ignore certain parts of your code.  In the code sample below, CustomSilverlightMethod will only be compiled when the SILVERLIGHT conditional is defined.

    public class Utilities
{
public static void SharedMethod()
{
// Method body here.
}

#if SILVERLIGHT

public static void CustomSilverlightMethod()
{
// Method body here.
}
#endif


}

This technique is useful when you have code that must run on different platforms.  Having the code in one place reduces the maintenance burden and reduces the chance for duplicated code.  I hope you will find this information helpful. Enjoy!


Feedback

# re: Sharing Code Between .NET and Silverlight Platforms

Gravatar Excellent. Now why no one ever blogged about this, is beyond me. Thanks for picking up that gantlet.
In a year and a half of doing Silverlight I've never anyone talking about sharing business logic publicly (or alternatively, I didn't listen)

One thing though, let's mention security concerns here.
Code shared on between the client and the server is code that should be assume is visible to the end-user. That's why having more granularity over the process of what exactly what get shared is necessary.

Imagine having "myCustomer" class that has some properties and some business logic you'd like to share, but also has "myTopSecretCustomBusinnessLogic" method that is sever-specific.

In this method of sharing business logic, you'd have "Silverlight" build mode and "Desktop" build mode that would partition what gets compiled where. I'd like something a bit more "business oriented" like a "SharedAttribute" over classes we'd like to share, and a "NotSharedAttribute" over stuff we don't want shared in those classes.
Oh well, I'm just ranting off here.

Excellent work :) 10/11/2008 11:17 PM | Justin-Josef Angel

# re: Sharing Code Between .NET and Silverlight Platforms

Gravatar Thanks for the feedback! I agree, it is very important to only share logic that "makes sense". I should have mentioned this in the article. Thanks for pointing that out! 10/12/2008 8:51 PM | pbrooks

# re: Sharing Code Between .NET and Silverlight Platforms

Gravatar you can just add many projects as you can, but including the same source files.

for example:

folder1/foo1.cs
folder2/foo2.cs
silverlight.csproj
winform.csproj
webform.csproj

all projects just simply include the files, without "add as a link" and "solution folder".
10/13/2008 1:19 AM | unruledboy

# 

Gravatar Domain-Driven Design and Silverlight 2 10/14/2008 1:34 PM | Yoot





 

Please add 8 and 1 and type the answer here: