Some time ago I came across the problem of compiling Silverlight 4.0 with Visual Studio 2010 when using XmlnsDefinitionAttribute attribute. I have reported the problem to Microsoft but for the time of writing this post I haven’t yet received confirmation of the bug. However more and more people around me start to experience the very same problem with VS 2010 so I’ve decided to publish some details towards the problem as well as possible workarounds that can be used until the bug is confirmed and some sort of hotfix is available.
The problem is that under some specific circumstances Visual Studio 2010 will fail compiling Silverlight 4 assembly if it refers to any other assembly via xmlns mapping in the root of the XAML.
Here you can find a sample solution that addresses this problem: VSBuildBug.
Here’s the brief overview of the sample code:
1. Silverlight 4.0 assembly “SharedComponents” contains a User Control called “SharedControl”
2. The assembly “SharedComponents” maps one of its namespaces to an Uri (in my case it is “http://denisvuyka.wordpress.com/vsbugs”)
3. Silverlight application “VSBuildBug” references “SharedComponents” assembly
4. Application contains a “MainForm” that is declared my means of the namespace mapping: <shared:UserControl xmlns:shared=”http://denisvuyka.wordpress.com/vsbugs”…
When you open the solution attached with VS 2010 and try compiling it you will receive the following error:
“The type or namespace ‘SharedControl’ could not be found (are you missing a using directive or an assembly reference?” (see the screenshot below)
However theoretically everything should compile without any problem. Some of the guys I’ve contacted towards this problem just gave up using xml namespace mappings thinking that the problem is in Silverlight itself but it’s wrong. This use case is absolutely correct and can be compiled.
The first workaround is calling “Build – Rebuild solution” several times in a row. At some stage you will receive “successful compilation” result and after that you will stop getting errors both for “Build” and “Rebuild”. However everything will be ok until the “Build – Clean solution” call or until you get a brand new version of the solution from the source control for example. Also different versions of Windows require different number of rebuild cycles. I didn’t bother figuring out the correct numbers, I can only confirm that on Windows 7 you may need about 3-4 “rebuild” calls while Windows XP may require 5+ “rebuild” calls.
After you made it compile you can reproduce the problem any time again. Just call “Build – Clean” solution and try “building” or “rebuilding” it again. The compilation problem will come back and you may need repeating the “rebuild” cycle one more time.
I’ve decided to go further with my investigation as I was wondering why TFS builds do not fail under the same conditions. I’ve ended up with a more reliable solution that I am using nowadays – msbuild tool.
If you unpack my solution once again and compile it from the VS command prompt using msbuild (just “msbuild VSBuildBug.sln”) you will never get an error. You won’t get errors calling “Build – Clean” solution and then using msbuild to build it as well.
So the second and most reliable solution is using msbuild tool to produce a solution. In case of avoiding full cleanups with “Build – Clean” solution developer may need calling msbuild only once getting a brand new version of codebase from TFS.
After finding a reliable workaround I’ve decided to go deeper into the details and see why auto-generated code is not compiling.
I’ve opened “MainPage.g.i.cs” with Visual Studio to get notifications when it is changed and to have an opportunity to see how it was changed. After a couple of experiments I’ve noticed that first two compilations (and code generations) does not produce the very same code behind actually.
Steps to reproduce:
Step 1. Open demo solution and call “Build – Clean solution”
Step 2. Call “Build – Rebuild”
You should see the same error I’ve described earlier:
If you open the auto-generated “MainPage.g.i.cs” you should notice that “MainPage” inherits “SharedControl” but no references to external component library are present (neither within “using” clause nor type declaration). See the screenshot below:
I completely agree that this code should not compile even theoretically and Visual Studio gives me the correct output stating about missing references.
Step 3. Call “Build – Rebuild” for the second time.
You should get the very same compilation error again:
However if you have “MainPage.g.i.cs” file opened in VS 2010 you will get a notification that its content was changed. Alternatively you can locate this file and open it manually.
After the second rebuild the type definition looks like the following:
As you can see now VS generated another version of code behind that correctly references the “SharedControl” type. The namespace is provided and code should theoretically compile fine. But it does not.
Step 4. Call “Build – Rebuild” 3rd time
You should receive notification that compilation was successful (please don’t forget about my notes at the beginning that I am using Windows 7, it was noticed that Windows XP environments sometimes require more “rebuild” calls).
Third compilation does not produce a new code behind file and its content is equal to those produced during the Step 3.
I’m pretty sure VS is doing something wrong between steps 2–4. Two different code generation outputs for the same action that was just called twice seems to be very suspicious.
The only idea I have for the moment is that “MainPage.g.i.cs” was generated AFTER the rebuild procedure has finished. And the 3rd rebuild is just using the file generated during the 2nd pass. If that is true then it makes a perfect sense why 3rd pass was successful. And if I’m right then developers may potentially encounter even more serious problems in the future because there will be always a possibility testing the code that was built without exception but does not contain changes or bug fixes that needs to be verified by developer if you see what I mean.
The only thing I don’t understand for the moment is why VS 2010 produces compilation errors while msbuild works fine. I expected VS 2010 is using msbuild under the hood for building Silverlight but my investigation results make me think that there are two ways of building (please correct me if I’m wrong, I didn’t try reflecting VS to find an answer for this question) and the build procedure embedded into VS is definitely having issues.
I still think that xml namespace binding is a very important feature that needs to be reused as much as possible (see more details here: “Prefixes and Mappings for Silverlight Libraries”) at least because of the following benefits:
helps a lot with xaml/code generation scenarios;
helps a lot with component discovery (we all love intellisense);
reduces a variety of problems related to code refactorings and type namespace changes;
I’m pretty sure Microsoft will provide a hotfix as soon as this issue is confirmed but meanwhile you can use “msbuild” or “continuous rebuild” workarounds to keep using xml namespace mappings within your projects.
Any feedback is appreciated.