I've been doing some MSBuild experiments lately and pondering what a build server should look like and ran into an interesting challenge:
Suppose I am trying to build an application that references some third party assembly (a pre-built assembly that is not part of the solution being built)--a good example of this might be a project that references
Log4Net. How can I ensure that my solution will build successfully and not encounter broken references to the third party assemblies that I use?
I know how to reconcile broken references on my desktop--I covered that in my
Resolving Reference Problems post. However, I shouldn't be checking in .USER files in source control, so that solution isn't relevant here.
I could hardcode a full reference path to something like C:\Program Files\log4net, but how do I know that's where the Build Masters have installed the binary?
You're probably saying, "Brad, you dummy, just add the binary to a solutions folder in your solution and reference it with a relative path!" Well, let's just assume that my friendly neighborhood Source Control policeman won't let me check in files that are not explicitly source code--of which, I guess, a DLL is not. What now?
What's interesting is that, so long as MSBuild can find my third party assembly in the GAC of the build server, it doesn't matter where the DLL lives in the rest of the file system: C:\Program Files\log4net, C:\Program Files\some-mysterious-sub-dir, wherever (or nowhere, as in, the Build Master deletes the binary after he installs it to the GAC).
Further, if you create such a scenario on your Dev machine and open up the project in Visual Studio 2008, you don't get the dreaded broken reference symbol (and your solution will compile). I wonder if that's a new thing in Visual Studio 2008? I could have sworn that Visual Studio 2005 would still show me broken references when my hintpaths wouldn't resolve to a physical assembly even if that assembly was in the GAC. Hmm.
Anyway, I had several JPGs to attach showing how I arrived at my conclusions, but I don't think this little factoid is worth all that extra work. However, feel free to play with the code yourself--attached are two solutions. One produces a signed class library and the other is a
WAP that references the DLL produced by the first solution. Build that class library, put it in the GAC, delete it from the bin directory, then see how the WAP can still build successfully.
GACRefTest.zip (332.83 kb)