S h o r t S t o r i e s

// Tales from software development

Archive for September 2011

The primary reference could not be resolved

leave a comment »

Last week one of my colleagues checked out the project that we’re working on and found that it wouldn’t build on her machine. This seemed rather odd as the project could be built successfully on my machine and on the build server.

This is a Visual Studio 2010 solution with four projects that targets the .NET 2.0 Framework. One of the projects references a common assembly called Vitality.Common.Data.dll containing routines to access MySQL databases.

When she tried to build the solution, one of the projects failed to build and the single error message indicated that namespace specified in a using statement and implemented in one of the other projects, which was referenced, was not found. This was very puzzling as there was no indication that the referenced project was failing to build.

At this point I was ignoring the warning messages and just concentrating on the error message. After a few minutes of unsuccessfull investigation I looked at the warning messages which, initially, seemed to make the problem even more puzzling:

The primary reference “Vitality.Common.Data” could not be resolved because it has an indirect dependency on the .NET Framework assembly “Accessibility, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” which has a higher version “4.0.0.0” than the version “2.0.0.0” in the current target framework.

As the solution targets the .NET 2.0 Framework and references a .NET 2.0 assembly, why did the warning messages reference .NET 4.0 assemblies ?

But the main puzzle was why this solution could be successfully built on other machines. Using the most basic diagnostic approach, what was different on this machine ?

I vaguely remembered that my colleague had recently been working on a .NET 4.0 project that used the MySQL .NET Connector and guessed that she had installed the .msi package for this. Neither my machine nor the build server had the MySQL .NET Connector installed and relied on the solution including a copy of the referenced MySQL assembly. Could that be the difference ?

Well, an install of the MySQL .NET Connector would almost certainly have put the assemblies in the GAC and this particular version, 6.3.6, includes assemblies built for both the .NET 2.0 and .NET 4.0 Frameworks. Could this be why references to .NET 4.0 assemblies were appearing in the warning messages ?

Suddenly, it made sense…

Project A references Project B
Project B references Vitality.Common.Data.dll
Vitality.Common.Data.dll has a dependency on MySql.Data.dll

There is no direct reference in the solution to MySql.Data.dll so when it’s built this dependency has to be resolved by probing for the assembly. This is where the difference between the machines becomes significant as it appears that the GAC is searched for the dependency, MySql.Data.dll, first and then, if not found, the directory where the directly referenced assembly, Vitality.Common.Data.dll, resides.

So, on both my machine and the build server, the copy of MySql.Data.dll that is in the same directory as the referenced assembly, Vitality.Common.Data.dll is used but on my colleague’s machine it is the copy in the GAC that is used.

The simple solution was to add a reference to the project that referenced Vitality.Common.Data.dll for the copy of the MySql.Data.dll assembly in the same directory as the Vitality.Common.Data.dll assembly. Once this was done the solution could be successfully built.

The only remaining question is why the dependency resolution process selected  the .NET 4.0 version of the MySql.Data.dll assembly from the GAC rather than the .NET 2.0 version…

Advertisements

Written by Sea Monkey

September 27, 2011 at 8:00 pm

Posted in Debugging, Development

Tagged with , ,

Abstract class or interface ?

leave a comment »

While adding some new functionality to a tracing and logging library I couldn’t decide whether I needed a new interface or a new abstract base class to implement a new feature.

I started with an abstract base class but changed my mind and used an interface instead. Then I changed my mind again when I realised that I needed the class constructors to be part of the contract.

There are times when it’s obvious that an interface definition is needed and similarly there are times when it’s obvious that a base class is the solution. But in situations where it’s not obvious, for example the implementation of internal code in an assembly, then deciding whether constructors are part of the implementaion contract may guide you to the answer.

Written by Sea Monkey

September 20, 2011 at 8:00 pm

Posted in Development

Tagged with ,

Different return types from Activator.CreateInstance

leave a comment »

While writing some IOC infrastructure code a few days ago I stumbled across the fact that Activator.CreateInstance() sometimes returns an ObjectHandle rather than an Object.

Perhaps I’ve led a sheltered life but until now I’ve only needed to use overloads of Activator.CreateInstance() that return an Object. This just needs casting in order to use it.

I’m not sure why this difference exists but it’s easy enough to deal with as the ObjectHandle class implements an UnWrap() method that returns the Object that the handle references.

Written by Sea Monkey

September 16, 2011 at 8:00 pm

Posted in Development

Tagged with ,

Different number of stack frames between Debug and Release builds

with one comment

I’ve recently been making some enhancements to a tracing and logging library that was written about four years ago. The tracing functionality uses the StackTrace class to get the stack frame of the caller and then logs information about the caller.

The updated code passed its unit tests and I created a new releae build but a few days later I found that the code repeatedly threw a NullReferenceException when called from the Main() method of a Windows console application.

After a few hours of debugging and head scratching the cause eventually became clear. The problem only occured with Release mode compiled code and initially I thought the problem might be due to code optimisation. After ruling this out by disabling optimisation in Release mode compiles, I realised that it was the Debug Info setting that is accessed using the Advanced button on the Build tab of the project properties page. The problem didn’t occur when this was set to Full (as used in Debug mode builds) but did occur when it was set to PDB Only (used in Release mode builds) or None.

Using the debugger to step through the tracing code it became clear that when Debug Info is set to Full there is an extra frame on the stack between the stack frame for Main() and the tracing code’s constructor. Presumably, the Full setting causes some interception code to be generated by the C# compiler that results in the additional stack frame. So, in Release mode builds the tracing code was stepping too far up the call stack and when the caller was the program entry point this caused a NullReferenceException.

I considered updating the tracing code to examine the stack frames and determine how far up the call stack it needed to step but was concerned that this might add a significant performance overhead when tracing is active. Instead, I decided to define conditional compilation constants to indicate which Debug Info setting is active. The stack frame constant is then defined conditionally. The tracing code needs to step nine frames up the call stack when Debug Info is set to Full or eight when set to PDB Only or None:

#if DEBUGINFO_FULL
        private const int BaseStackFrameOffset = 9;
#endif
#if DEBUGINFO_PDBONLY || DEBUGINFO_NONE
        private const int BaseStackFrameOffset = 8;
#endif

Written by Sea Monkey

September 14, 2011 at 8:00 pm

Posted in Debugging, Development

Tagged with , ,

Problems with xsd.exe

with one comment

I’ve been using Microsoft’s XsdInfer.exe and XsdObjectGen.exe utilities since they were released seven or eight years ago without any problems but about a year ago I needed to generate C# class source code for a complex set of schemas and found that the task was beyond XsdObjectGen.

The xsd.exe utility that ships with Visual Studio and the Windows Platform SDK supercedes XsdInfer.exe and XsdObjectGen.exe but while I’ve used xsd.exe to generate custom datasets over the past six years I’ve never used it to generate XmlSerializable data classes. So, it was a relief to find that xsd.exe successfully the C# classes  I needed and that these performed without any problems.

Over the past few weeks I’ve been updating our build processes and this seemed to be a good opportunity to phase out XsdInfer.exe and XsdObjectGen.exe in favour of an up to date distibution of xsd.exe.

In hindsight I shouln’t have wasted the time and effort because I just encountered one bug after another. Do a search for xsd.exe at Microsoft’s Knowledgebase web page:

http://support.microsoft.com/search/default.aspx?query=xsd.exe

and you’ll get a list of 21 bugs and problems.

Even when I wasn’t encountering bugs, the data classes it generated appear to be a step backwards. For example, repeating elements are represented as arrays without an IEnumerable implementation so that the foreach() syntax I’ve happily been using for years can no longer be used.

Amongst the behaviour that I’d classify as odd if not an outright bug is that when using inferring an XSD from an XML file, an attribute on an element causes it to be treated as a repeating element. If the intention is for the element to be a single item then this requires that the element is referenced as the first element type in an element type array rather than just the element type, e.g.

ConfigurationFile configFile = myClass.ConfigurationFile;

 
must be replaced with

ConfigurationFile configFile = myClass.ConfigurationFile[0];

 
which implies that there might be multiple ConfigurationFile elements.

This can be fixed by editing the XSD created by xsd.exe but this is not a viable solution in our automated build processes.

A related problem that definitely is a bug is that in some circumstances the serialization attributes in the class code generated by xsd.exe do not correctly describe the types being serialized. This shows up as a serialization failure at runtime with the following error messages:

Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'xxxxxxxx[]' to 'xxxxxxxx'
error CS0029: Cannot implicitly convert type 'xxxxxxxx' to 'xxxxxxxx[]'

 
Examination of the class code shows that the the relevant XmlArrayAttribute has been specified with typeof(xxxxxxxx) when it should be typeof(xxxxxxxx[]). There’s a good blog post on this problem here.

Written by Sea Monkey

September 12, 2011 at 8:00 pm

Posted in Development

Tagged with ,

Replacement for Reflector

leave a comment »

Inevitably, Red Gate announced earlier this year that it was going to start charging for .NET Reflector.

I say “inevitably” because why would a commercial organisation commit valuable time and resource to something that doesn’t add directly to its bottom line ? It’s a shame that when Lutz Roeder decided he could no longer commit the time required to developing and maintaining Reflector that it ended up with a commercial organisation. You can’t blame Lutz for earning a little bit of money for all his hard work but I would question why Red Gate bought it unless it had already decided that, sooner or later, it would only provide it for a fee.

While Red Gate should be applauded for the developing and maintaining Reflector over the past few years, personally I’ve found the developments either irrelevant or irritating. For example, the integration with Visual Studio created problems that never existed before. For example, the ‘auto update’ feature would insist on downloading the latest version and attempting to install it only to fail if you happened to have a copy of Visual Studio running. No helpful error messages either, it would just fail with an error that, if you thought about it hard enough, you’d realise meant that Reflector must be running somewhere.

I hope that Red Gate realise the bad feeling that their change in policy has already generated and will probably continue to create. If it seems a bit dumb for a commercial organisation to give away free stuff that cost it time and money to develop then the only thing worse is for it to then suddenly start charging for it. It’s inevitable that most users will feel that something has been taken away from them.

For now, running the old version 6.x release probably covers my needs. The cost of a basic licence for Reflector doesn’t seem unreasonable and Red Gate say it’s a one-off payment for a perpetual licence but presumably that’s only for version 7 and 7.x updates. So, that just means that it’s in Red Gate’s interests to release version 8.0 as soon as possible and charge for upgrades. If this sounds cynical then remember that this is the company that said it wouldn’t charge for Reflector and then reneged on that commitment.

There are some freeware alternatives. Ironically, the fact that Reflector was free was probably stifling any alternative implementations. ILSpy looks promising…

Written by Sea Monkey

September 9, 2011 at 8:00 pm

Posted in Debugging, Development

Tagged with , ,