Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Silverlight and WPF - Sharing Library Projects
Mike Taulty's Blog

Mike's Badges

Follow on Twitter
View mike's profile on slideshare
Add to Technorati Favorites
CW Blog Awards

One thing that I got asked a couple of times down at REMIX UK was the question of;

How come I can't reference a regular .NET library from a Silverlight project?

Which really comes down to the CLR that's in Silverlight ( the "CoreCLR" ) not being the same CLR as you see on the desktop or the server.

What do you do about this? If you've got some code that you want to build into a library that will compile against both the full .NET Framework and the Silverlight .NET Framework then one thing you might try is to set up two projects that point to the same source code.

That is, you can make a full desktop library;

image

Add your code;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyLibrary
{
  public class MyClass
  {
    public void MyMethod()
    {
    }
  }
}
and then create another Silverlight library project;
image 

and then link the source files from one project to the other as in;

image

and then add the source file as a linked item;

image

and you end up with the same source file in 2 projects;

image

What I'd actually prefer is to be able to get one project that would build the same source in both a Silverlight Configuration and a "Desktop" configuration producing 4 outputs;

  • Desktop Debug
  • Desktop Release
  • Silverlight Debug
  • Silverlight Release

I made an attempt at this but I don't think my attempt really cuts it so if someone has a proper way of doing this with Visual Studio and MSBuild then that'd be interesting to know about although I have a feeling that it's going to prove to be an unrealistic approach.

Here's my attempt anyway.

Create a new desktop library project in Visual Studio;

image

Add in to this library a couple of new project configurations - Debug Silverlight  and Release Silverlight;

image

image

image

Reopen the project file as an MSBuild file and attempt to hack settings from a Silverlight project into the MSBuild file. This has me ending up with a rather clunky looking MSBuild file like;

 

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{FE8C29DB-40B4-48EE-9CC0-4A8273E99DCA}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>DualPurposeLibrary</RootNamespace>
    <AssemblyName>DualPurposeLibrary</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup Condition=" '$(Configuration)' != 'Release Silverlight' AND '$(Configuration)' != 'Debug Silverlight' ">
    <Reference Include="System" />
    <Reference Include="System.Core">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Xml.Linq">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data.DataSetExtensions">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Class1.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  
  <!-- BEGIN SILVERLIGHT COPIED SETTINGS -->
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug Silverlight|AnyCPU' ">
    <OutputPath>bin\Debug Silverlight\</OutputPath>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants>
    <NoStdLib>true</NoStdLib>
    <NoConfig>true</NoConfig>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release Silverlight|AnyCPU' ">
    <OutputPath>bin\Release Silverlight\</OutputPath>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE;SILVERLIGHT</DefineConstants>
    <NoStdLib>true</NoStdLib>
    <NoConfig>true</NoConfig>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup Condition=" '$(Configuration)' == 'Release Silverlight' OR '$(Configuration)' == 'Debug Silverlight' ">
    <Reference Include="System.Windows" />
    <Reference Include="mscorlib" />
    <Reference Include="system" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Net" />
    <Reference Include="System.Windows.Browser" />
  </ItemGroup>

  <Import 
    Condition=" '$(Configuration)' == 'Release Silverlight' OR '$(Configuration)' == 'Debug Silverlight' "
    Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight\v2.0\Microsoft.Silverlight.CSharp.targets" />
  
  <!-- END SILVERLIGHT COPIED SETTINGS -->
  
  <Import Condition=" '$(Configuration)' != 'Release Silverlight' AND '$(Configuration)' != 'Debug Silverlight' "
          Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  
  
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

and I seriously suspect that this isn't anything near to being correct at this point.

It does seem to "sort of work" from the point of view of being able to walk up to MSBuild from a command line and say;

  • msbuild dualpurposelibrary.csproj /p:Configuration="Debug"
  • msbuild dualpurposelibrary.csproj /p:Configuration="Release"
  • msbuild dualpurposelibrary.csproj /p:Configuration="Debug Silverlight"
  • msbuild dualpurposelibrary.csproj /p:Configuration="Release Silverlight"

but loading this project into Visual Studio looks to confuse Visual Studio.

You'll notice that I ended up putting hacky looking Conditions into my MSBuild file in order to keep MSBuild happy and I suspect that Visual Studio doesn't apply conditions in the same way - there's a forum post up here;

http://social.msdn.microsoft.com/Forums/en-US/msbuild/thread/a48b5b57-215c-44f9-b750-106efe3ea023/

which highlights some of the differences around conditions and if I build the 4 configurations of this project in Visual Studio then what I look to end up with is 4 non-Silverlight assemblies rather than 2 Silverlight assemblies and 2 non-Silverlight assemblies.

So...I figure for the minute that perhaps the 2 separate projects with the linked files is the way to go but I'm guessing that someone out there has enough MSBuild/Visual Studio Project knowledge to put this together and make it work?


Posted Sun, Sep 21 2008 4:49 AM by mtaulty
Filed under: ,

Comments

Silverlight and WPF - Sharing Library Projects | Today's Bargain Electronics Store wrote Silverlight and WPF - Sharing Library Projects | Today's Bargain Electronics Store
on Sun, Sep 21 2008 5:19 AM
Dew Drop - September 21, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - September 21, 2008 | Alvin Ashcraft's Morning Dew
on Sun, Sep 21 2008 7:04 AM
Reflective Perspective - Chris Alcock » The Morning Brew #184 wrote Reflective Perspective - Chris Alcock &raquo; The Morning Brew #184
on Mon, Sep 22 2008 12:10 AM
Community Blogs wrote Silverlight Cream for September 22, 2008 -- #374
on Mon, Sep 22 2008 11:03 PM
Rob Houweling with a Jeff Paries Sneak Preview, Devin Rose with &amp;quot;Mountain Pass Tower Defense&amp;quot;
2008 September 23 - Links for today « My (almost) Daily Links wrote 2008 September 23 - Links for today &laquo; My (almost) Daily Links
on Tue, Sep 23 2008 4:37 AM
Silverlight news for September 23, 2008 wrote Silverlight news for September 23, 2008
on Tue, Sep 23 2008 6:24 AM
(C) Mike Taulty, 2009. All rights reserved. The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems