How to make sharing code between .NET and Silverlight (a little) less painful

Windsor ships for both .NET and Silverlight. However working with the codebase in such a way that we can target both runtimes at the same  time with the least amount of friction possible proved to be quite a challenge.

Problem

We’re using single .sln and .csproj files to target both runtimes (actually 5 of them, as we ship for 3 versions of .NET and 2 versions of Silverlight, but I digress) with some heavy (and I mean-  really heavy) Jedi trickery in MsBuild by Roelof.

We’re using conditional compilation to cater for incompatibilities between frameworks. For example, SerializableAttribute and NonSerializedAttribute are not present in Silverlight, so many of our classes look like this:

#if !SILVERLIGHT
   [Serializable]
#endif
   public class ParameterModel
   {
      // some code here
   }

This is quite cluttering the code making it harder to read. It adds friction to the process, since I have to remember each time to exclude the attribute from Silverlight build. Even more annoying is the fact, that ReSharper is not very fond of pre-processor directives in code, and certain features, like code clean up and reordering don’t really work the way they should.

Solution

I figured out a way to cut the need to use conditional compilation in this case. So that I can write the code like this:

[Serializable]
public class ParameterModel
{
   // some code here
}

and still have it compile properly under Silverlight, outputting exactly the same code as the first sample. How you ask? – using a not very well known feature of .NET BCL – ConditionalAttribute.

Entire trick works like this: I replicate the Attributes conditionally for Silverlight builds, applying ConditionalAttribute on top of them with some fake condition that never will be true. That way the compiler will not complain when I compile the code, because the attributes types will be defined and visible, however thanks to ConditionalAttribute they won’t be applied to any of my types. To make them not visible to the outside world, I make them internal. Here’s what it looks like:

#if SILVERLIGHT
namespace System
{
    using System.Diagnostics;
 
    [Conditional("THIS_IS_NEVER_TRUE")]
    internal class SerializableAttribute : Attribute
    {
    }
 
    [Conditional("THIS_IS_NEVER_TRUE")]
    internal class NonSerializedAttribute : Attribute
    {
    }
}
#endif

I am on a horse.


Posted 11-16-2010 11:18 AM by Krzysztof Koźmic
Filed under:

[Advertisement]

Comments

Randalll Sutton wrote re: How to make sharing code between .NET and Silverlight (a little) less painful
on 11-16-2010 8:20 AM

You are a genius! Thank you for this tip.

Christopher Bennage wrote re: How to make sharing code between .NET and Silverlight (a little) less painful
on 11-16-2010 9:18 AM

Very nice.

Prabir Shrestha wrote re: How to make sharing code between .NET and Silverlight (a little) less painful
on 11-17-2010 10:59 AM

nice trick, but i wouldn't recommend it much. coz those classes would still be present internally in the .dll file but hidden to the outside world as you mentioned.

if you look from a javascript side, devs there try to reduce the size, by removing semi-colons, renaming vars. but in .net side we hardly see people talking about these. :-(

been always wondering when will silverlight and .net devs start to think of performance and size seriously.

Uwe wrote re: How to make sharing code between .NET and Silverlight (a little) less painful
on 11-17-2010 2:15 PM

Prabir your comment shows that you don't know anything about .NET. Semi-colons and variable names don't affect performance in a real language. Javascript is like the name says a scripting language and therefore a very different beast. Don't blame developers for not thinking about problems they don't actually have.

Mark wrote re: How to make sharing code between .NET and Silverlight (a little) less painful
on 11-17-2010 3:07 PM

I often use partial classes and platform-specific files for class re-use. I can't remember if I've used it for attributes but i think it would work.

So in WPF project we have ParameterModel.cs which has shared code:

public partial class ParameterModel

{  

  // Shared Code

}

This file is also linked in Silverlight project

In WPF project we also have

ParameterModel.Wpf.cs

which has

   [Serializable]

   public partial class ParameterModel

   {

      // Other Wpf-specific code here

   }

Rick wrote re: How to make sharing code between .NET and Silverlight (a little) less painful
on 11-18-2010 8:04 PM

I'm the man you're man could code like. Look up, look down, now back to me. Look, the code is now diamonds...

Blog J.Schweiss wrote Thinking about revision control
on 01-29-2011 2:16 AM

Thinking about revision control

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)