Removing Design Time references at compile time

As you might have noticed on my blog, I like working with Silverlight, and I like using the MVVM pattern when I do so. As a part of this, I generally create design time ViewModels to get the best help from the tools (VS and Blend). VMs

The annoying thing about this, is that project containing the design time information need to be referenced by the application for the whole thing to work. But when the app is built and released, I really don’t want the extra ViewModels to be included in the xap file. I guess, in most cases, they are fairly simple and small, making the xap bloat minimal. But it still feels wrong. And it feels even worse when your design time VMs become large due to embedded resources such as images and data…

What you see below is a typical example of a (somewhat simplified) solution


As you can see, there is the Silverlight application, the hosting website and the 2 VM projects. To get the design time VMs to work, the Silverlight application obviously need to reference the project that contains them. The downside to this is, as mentioned before, that the design time assembly will be added to the xap file.

So…what can we do? Well, prior to building the application, we can go in and remove the reference. But won’t that cause the build to break? No, it won’t. As I use the “d” namespace to reference my design time VM, and set it to be ignored, the referenced assembly isn’t actually needed for the app to run. It is only used at design time.

mc:Ignorable="d" d:DataContext="{d:DesignInstance Type=dvm:MyViewModel, IsDesignTimeCreatable=true}"

Ok, so that is cool! But it is really annoying having to go in and remove the reference before each build. So are there any options? Well, yes there is…

The xap file can be renamed to zip and opened, and the assembly can be removed before the file is renamed back to xap. But once again we are talking about a lot of work. Options? Well, you could automate the whole thing using a post-build event.

But seriously, there has to be a better way!!! And there is…

Start by unloading the Application project by right-clicking it and selecting “Unload Project”. Next right-click it again and select “Edit <Your Project Name>.csproj”. This will open up the project file, showing all of its glorious XML. This XML is used by MSBuild to figure out what needs to be done. And if you look around the XML, you will notice little statements beginning with “$”. These statements add logic for the build process. A lot of these “build logic statements” are inside an attribute called “Conditional”. And this is where it gets useful.

The Conditional attribute basically says that the XML tag is only supposed to be used by MSBuild is the statement inside is true. Hmm…we can use this… If you look a bit down the XML, you will find a bunch of XML that will resemble you project structure a lot (for pretty obvious reasons). In among all this XML, you will find all the references that the project is using. There is one ItemGroup for assembly references, and one for project references.

If you locate the reference element that points towards your design time VM assembly, and a Conditional attribute with the value “false”, then that reference will not be added when you build your project.

In my case it looks like this

<ProjectReference Include="..\ConditionalReferenceDemo.ViewModels.DesignTime\ConditionalReferenceDemo.ViewModels.DesignTime.csproj"
<ProjectReference Include="..\ConditionalReferenceDemo.ViewModels\ConditionalReferenceDemo.ViewModels.csproj">

That’s it! Now my design time VMs work great in design time, but are not added to the xap when the application is built. It isn’t rocket science, but it does help out…


Pingbacks and trackbacks (1)+

Comments are closed