Using NTFS symbolic links instead of HintPath

Topics: General
Feb 21, 2013 at 10:29 AM
Just throwing an idea out there:

Instead of adding HintPath in the csproj References, one could make symbolic links to all the required assemblies in a single folder.

This would let top level projects declare only their build time, direct dependencies in their references, instead of having to list ALL direct and indirect references in the cs proj.

Does that sound silly?
Feb 22, 2013 at 10:34 AM
The intent isn't silly at all, but the proposed implementation has issues.

It doesn't work with all file systems or have the same mechanism on all operating systems.

A much better approach may be to modify the msbuild step responsible with providing the list of available assemblies to interrogate based on metadata dependencies, and populate this using the content of the packages directory at build time (don't remember the name of this target off the top of my head). Although we have not gone that far internally yet (it is on the drawing board) we do run a modified vsix to allow turning off the addition of hint paths for transitive references, something you would also need to have for this to work well. You would also have a few issues with packages that include transitive dependencies as dlls within the package rather than as package dependencies (as the former case requires you to either flag or infer which are direct and which are transitive).

Of course you could argue that this approach has similar shortcomings as those initially mentioned, due to xbuild not providing all the required functionality under mono, but at least the file system does not need to be a consideration.
Feb 22, 2013 at 11:48 AM
Very interesting!

BenPhegan wrote:
(...) modify the msbuild step responsible with providing the list of available assemblies (...)
Are you talking about the BeforeResolveReference and AfterResolveReferences targets mentioned here ?

BenPhegan wrote:
(...) to interrogate based on metadata dependencies (...)
Just taking the list of assemblies provided by the packages in the packages.config would be enough, wouldn't it?

BenPhegan wrote:
(...) we do run a modified vsix to allow turning off the addition of hint paths for transitive references (...)
Do you mean turning off the addition of transitive references altogether ? or just the addition of hint path ?
Mar 14, 2013 at 12:53 PM
Sorry for the long pause.

I thought I would just put an example together. If you grab this:

You will find:

1) Two solutions, each with a NuGet package dependency on Castle.ActiveRecord (just a random one I was familiar with). They started as direct copies.
2) One (TransitiveTestNew) has had all direct references removed from the .csproj other than Castle.ActiveRecord.dll.
3) TransitiveTestNew has had a new .targets import added that calculates the location of package directories and adds it to the AssemblyResolvePaths (this is not a new technique, you can find it places like here:
4) If you run Build.cmd you will find the output directories should be almost identical (so transitives are included in output without direct references) other than an assembly that is not directly referenced nor required transitively.

Also, in answer to your questions:

1) Yes.
2) No. The packages.config can get out of sync with what is even referenced by the .csproj, so it is a good starting point but you need to get ALL the assemblies that are provided by NuGet and allow the compiler to whittle down the result.
3) Both. We don't add either....we just stop the traversal. This is particularly useful when you are building a library and its output will never be run directly (in which case we generally state the runtime dependencies as part of the nuspec).

Hope that helps! Now, off to raise this as a feature would be nice to get rid of those direct references without running forks of NuGet!