I am one of the proud folks that gets to work on the System.ComponentModel.DataAnnotations assembly. This assembly is used by several products, and it seems more are starting to depend on it. Part of the fun with this assembly is that it exists for both Silverlight (as of Silverlight 3), and the full .NET Framework (as of .NET 3.5 SP1).
I am responsible for managing source code sharing of this assembly for the two frameworks; in fact, I’m doing some work today related to this. Phil asked me for tips on how to work on projects that need to support both frameworks, and here’s what I came up with. Nothing ground-breaking, but worth documenting and sharing.
- Sharing source between the frameworks comes with a tax, but I believe it to be justified. As development is ongoing, or changes are being made, sharing source is going to be the easiest way to keep things in sync. You'll find yourself using #if SILVERLIGHT and #if !SILVERLIGHT in some places, but it’s usually not terrible.
- One of the hardest questions, as silly as it is, is “What do we call the 2 frameworks?” “Silverlight” is obvious, but what to call the “regular .NET Framework?” On our team, we've referred to it as "Desktop” for lack of a better term. It will be important that the team settles on the two terms for the frameworks, to safeguard against communication issues. I recommend using these terms as folder names in the source tree to get the terms ingrained in the team members’ heads.
- There are several ways to share source: (I would recommend trying option 2 first)
- Manually make one of the frameworks the “master” project containing the source files, and the other framework the “slave” project, with linked files.
- Patterns and Practices Project Linker. While I’ve not used it, I’ve seen it used and it’s pretty sweet. One framework (probably Desktop) is the “master” (source) and the other is the “slave” (target). This will basically automate #1 if you can depend on all developers having the tool installed.
- Dual Slave projects (which is what I use). Instead of a Master and a Slave, make both projects slaves with linked files.
- Benefit: No fretting over which project is the “master” – ‘cause we developers tend to get stuck on stupid questions like that.
- Benefit: Allows you to keep the actual project files (which differ for the 2 frameworks) separated from the source files a little better.
- Benefit: You can then more easily branch the source code separately from the projects (which I’ve had to do for DataAnnotations)
- Disadvantage: Adding, removing, moving, and renaming files is a PITA
- Probably a dozen more
- Whatever approach you use for sharing framework source, use the same approach for sharing unit test code.
- One difference is that you’ll be using the Silverlight Unit Test Framework for the Silverlight unit test project, and VSTS for your Desktop unit test project.
- Or other unit test frameworks if you so choose
- Even with this difference, it’s pretty straight forward for sharing unit test files. Same deal as the framework – you’ll have 2 separate project files, but they'll share source.
- Be sure to write unit tests so that they can be properly verified in Silverlight:
- Don’t assume English culture, ever – the Silverlight runtime will respect the client culture, and it’s a good idea to execute the unit tests under different cultures.
- Don’t assume you get exception messages from the core – the Silverlight non-developer runtime truncates exception messages to save space. So if you have a unit test that (for instance, like we had in DataAnnotations) asserts on an exception coming from the RegEx constructor, the test will fail on the non-developer runtime in Silverlight.
Hope this helps!