The Issue

One issue that I have ran into many times is the issue of trying to use version specific DLLs in a .NET solution we’re deploying to a client and that client having a different version of that DLL in their global address cache (GAC). Because of the way .NET handles this situation, when it tries to load a referenced DLL, if the framework finds a DLL of the same signature in the GAC, it will use the GAC version regardless of the version (even if it is not the same as the one that was used during the compilation of the solution). Obviously this can cause issues especially if you don’t have control over the referenced DLLs. We ran into this issue using the Microsoft SQL DLLs (I lothe Microsoft.SqlServer.BatchParser in ways that are unquantifiable).

The Resolution

Here’s where Costura comes to the rescue, to show this process I created a test project and added some SQL DLLs as references to the project.

And when you build this project you get an EXE with those SQL DLLs in the bin/Debug folder.

This poses an issue if the computer this is ran on has another version of these DLLs in its GAC as it will use those versions instead of those in this folder. So now let’s add Costura to the project via Nuget.

You’ll notice that Costura is added as a reference and the FodyWeavers.xml is added to the project. Modifying the FodyWeavers.xml allows us to add unmanaged assemblies (like the BatchParser) as part of the project too.

Now that Costura is added, any project reference we set Copy Local as True will be compiled into the resulting project EXE.

Now when we build the bin/Debug folder looks a lot less cluttered, you’ll notice all of the DLLs are now gone and we have only the project’s EXE sitting in there. You may notice that the size of the EXE has increased dramatically. This is because it now contains all of the referenced DLLs.

 

When we run the project now, since the application does not have to reference an external reference for those DLLs, it does not look in the GAC and therefore will not use an unintended version of the DLL regardless of what the client has installed on their machine.