The Visual Studio Solution I have been using for a while has grown to 11 projects. It's also dependant on a bunch of libraries from a resuable framework I've been working on which I intend to use across various products. Since working in XAML, I broke off the client components to lighten the burden on the IDE. Problems arose after I made some major changes to my resuable framework.
The framework I have is an evolving beast that I call Steelcore. My vuPlan projects use various libraries from this framework by referencing the release built DLLs.
Since VS 2010 is around the corner and has a slew of thread debugging features, and due to an issue with the way I added tracing instrumentation to my code, I cut out a few classes related to thread tracking and even entire namespaces and re-versioned to 126.96.36.199.
This is not an issue for my unfinished vuPlan project as I own the source and I can just right-click each reference under each vuPlan component, check its property sheet states 188.8.131.52 and rebuild the lot. Nothing else to worry about right?
Right. All was fine when building, sure, but when working in my light-weight solution (just has the WPF client bits) and I tried to run it.
Could not load file or assembly 'Steelcore.Data, Version=184.108.40.206, Culture=neutral, PublicKeyToken=abcdef0123456789' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
An interesting point about the way I've written the vuPlan client is that it has only the skinniest of clients, just UI, and the implementation logic is downloaded from the web at startup, loaded with reflection and plugged-in to the UI using polymorphic viewmodels. One day I shall blog about that. But the reflection part of the scenario is a red-herring and I troubleshot the problem as if it were an ordinary 'early bound' load error.
The exception was being thrown by a class that downloads the implementation assembly and enumerates the types within. Just the enumeration caused it to blow up. Needless to say, I rebuilt and ensured my implementation assembly was up-to-date and that the locally cached copy was, too.
My first mode of attack was to double-check all references within all projects, in all solutions including the Steelcore library itself, just in case one component was using an old version or using a version that was using an old version.
I also made a decision to increment the minor version number of all vuPlan assemblies to reflect their dependence on the radically different Steelcore DLLs. This would prove useful later.
My second was to fire up I'll Dazzle 'em (ILDASM.exe) and take a peek at the manifest. This was a good move because within the list of references was this intriguing bunch of text:
.assembly extern Steelcore.Data as Steelcore.Data_13
.publickeytoken = (80 72 6D A9 F7 97 F6 5E ) // .rm....^
Must admit it might have said "as Data_13" I'm not sure because my machine crashed on resume from sleep just before typing this and I lost the original paste.
Anyway, there were TWO references to Steelcore.Data.dll and the one above looks like some auto-gen alias to help it reference an old version probably by proxy, i.e. probably because some other reference references it.
So my final tool was Fuslogvw.exe which is the Fusion log viewer/manager. Fusion is the name for the bit of the .NET Framework that goes looking for referenced assemblies and so this would prove most useful indeed. This was Suzanne Cook’s baby when she blogged and her articles haven’t lost any of their usefulness.
The interesting section is obviously the blue section. Here we see that two S26.Vuplan.Core libraries are being loaded, each of differing versions, and that dastardly Steelcore.Data 220.127.116.11.
Each item in the log opens an HTML doc which shows further information.
And as expected, the "Calling assembly" line shows that it is the old version of Vuplan.Core that's causing my grief.
Despite having thought I'd checked each of the assemblies, I'd clearly missed one. Aware that an old copy of the core lib was being referenced, I suspected and double-checked the client components again and found the bad reference.
I twigged that when I'd broken off those projects a few weeks ago, I must have reset the references to the built DLLs although I still find it unusual that it didn't just pick up the new version and work - my references to Steelcore did! Maybe it was pointed at a different path or something.
Blames His Tools
What would have helped was if Visual Studio had a different colored icon for project references and static file references.
It'd also be nice to see the version number next to each reference.Labels: programming