Saturday, 22 March 2008

Silverlight projects vs. normal projects, and how to convert a normal project to a Silverlight project

For those of you that use the Silverlight tools for Visual Studio, you have probably tried adding a reference from a Silverlight project to another non-Silverlight project in the same solution, just to see what happens. If do so, you will be met with the following message:



Or if you try to do it the other way round:



Why is this? Well, Silverlight uses different CLR to the rest of .NET, known as the CoreCLR. The CoreCLR is a stripped down version containing only the stuff deemed necessary by the Silverlight team. Also, if you look at the version number of any of the Silverlight assemblies (e.g System.Xml) you will see that the version is 2.0.5 whilst the version of System.Xml in a non-Silverlight assembly is 2.0.0. They are not binary compatible.

So imagine the situation where you have a class library which you wish to build for Silverlight consumption. There are two solutions:

1. Create a new Silverlight class library, and add all the class files to the project. This is fine for a small project.

2. Edit the .csproj file manually, and convert it to a Silverlight project. This is good if you have a large project with lots of file and subdirectories.

I originally looked into this because I wanted to convert to the Ninject.Core, a lightweight dependency injection framework (www.ninject.org), to Silverlight. It wasn't too hard - here are the steps to do so:

- Add the following lines in the first <PropertyGroup> section:

  <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<SilverlightApplication>false</SilverlightApplication>
- In the DefineConstants section, add a define for SILVERLIGHT and clauses to specify not to build against standard libraries, e.g
  <DefineConstants>TRACE;DEBUG;SILVERLIGHT</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
- Change <Reference include="System"> to <Reference include="system">

- Add the following lines right at the end (just before the </project> tag)
  <ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
<SilverlightProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
Hope this helps
Neil

7 comments:

Anonymous said...

Brilliant, thanks for the tip. I have been hunting around for an IOC for silverlight, and with this tip looks like my search is over. Now just need to get an event broker working..

BTW the XML in the csproj file is case sensitive, so might be worth updating your blog to have the xml in the correct case.

stuart said...

Neil

Did you manage to get Ninject working on Silverlight? Ninject uses Reflection Emit, and my app falls over with a MethodAccess exception every time Ninject tries to call these methods. Did you find a way around this?

Stuart.

Neil Mosafi said...

Anonymous - thanks a lot for the feedback, I will check out any casing issues that may be hidden in there.

Stuart - Regarding NInject, you are indeed correct. Despite eventually being able to get the core to compile, I was unable to get it to run. This is really because of Silverlight's new Security policies which means things like Thread.StackTrace cannot be accessed.

Both - The good news is that I have developed by own IoC framework for Siverlight. Now it's fairly primitive but it seems to have done the trick on the project I am working.

I will shortly blogging about this framework and the other MVC classes it provides, but you can download it at http://code.google.com/p/silverstone/

Neil

Michael Sync said...

I converted Microsoft Unity Framework for Silverlight. Converting "big" .NET class library to Silverlight Library is not that easy as changing the version number or path.

Anonymous said...

you need to add a closing tag in the second solution in the CSPROJ file:

Anonymous said...

You are brilliant.That is great. Thanks

Neil Mosafi said...

LOL, thanks! Amazed this still works after all these years!