5

When adding either 3rd party libraries or internally developed ones to a C# project, I usually just add the reference in the Visual Studio solution browser. However, this creates an absolute path reference to the library. When another developer on a different computer checks out the code, they probably won't have those libraries in those exact folder locations.

Where do you put your 3rd party libraries? suggests that 3rd party libraries should be kept in a folder inside the solution folder (i.e. the repository folder). This makes sense to me. However, when I add the references they are still absolute path references. Changing C# .dll references from absolute to relative offers a solution to this, however, is manually editing the .csproj file really the way to go? I've read that it is not recommended to mess around with the .csproj file. Also, I see in the comments to that question that if your library is not above the project folder (so in my case I created a dependencies folder inside the project folder, not the solution folder), then VS should make the path reference relative by default but that did not happen in my case.

Then there is the question about internally developed libraries. In my case I have a utilities project that has functions I need to use across multiple solutions. I would prefer not to have to manually update the library in each project that relies on it. This is not a problem if I use absolute paths to the reference but then what happens with using version control? In the first question I linked to, one of the lower down answers suggests using a program called Sync Toy to make sure that the library gets copied into all the projects that reference it's dependencies folder. Is that a sensible way to go?

Lastly, and this last point may be too unrelated to fit in the same question, when I add the reference, but default it coies the library to the output directory on building. But that means when I deploy the project I have to copy all those additional dll files. Is there a way to avoid this and embed the library into the output .exe?

Community
  • 1
  • 1
Dan
  • 45,079
  • 17
  • 88
  • 157
  • *"when I add the references they are still absolute path references"* How are you adding them? When in a project I reference a DLL sitting in a directory at the root of the solution the reference are added as a relative path (`../Libraries/SomeLibrary.dll`), not an absolute one. – Albireo Dec 17 '15 at 09:25
  • @Albireo I am right clicking on References in the solution explorer, choosing *Add Reference*, choosing *browse* and then navigating to the .dll file and selecting and adding it – Dan Dec 17 '15 at 09:28
  • That's weird, I tried right now to confirm it (in VS 2015 and 2008) and it works, the path to the library is relative. Where are you checking the path? The *Properties* windows or the *.csproj* XML content? The former always shows the absolute path, even if the latter has it stored in as relative. – Albireo Dec 17 '15 at 09:32
  • @Albireo I was checking in the *Properties* window. Let me push the project and see if it is relative on another computer then... – Dan Dec 17 '15 at 09:34
  • 1
    You don't need to do the check on another computer, simply open the *.csproj* in a text editor and check the reference's *HintPath*, it should begin with `..\ ` or `.\ `. – Albireo Dec 17 '15 at 09:35
  • @Albireo it doesn't, but it also doesn't have to full path starting from C:\ so that is promising... – Dan Dec 17 '15 at 09:36
  • @Albireo OK so they are relative in that case, I did not realize that the *Properties* differed from the .csproj. So that solves the 3rd party libraries question but not the internal libraries one. – Dan Dec 17 '15 at 09:44

1 Answers1

7

Reference path, absolute or relative?

When you add a reference through References > Add Reference > Browse > Browse… Visual Studio will save the relative path to the library in the .csproj.

However, if you look at the reference properties in the Properties window Visual Studio will show you the absolute path to the library (I don't know why someone thought it would be a good idea to do it):

Solution explorer

Properties window

Project file

This has been tested in Visual Studio 2008 and 2015.

Common library, how can I share it?

If you have a common library you need to share between solutions (not projects) I recommend, if possible, to create your own NuGet feed and leverage that.

You probably want a Remote Feed, not a Local Feed; there are many tools to create and maintain one (e.g. TeamCity).

The library is updated? Push it to your internal NuGet server and enjoy the updates.

Moving assemblies around

when I add the reference, but default it coies the library to the output directory on building

Well, that's how it works in .NET.

that means when I deploy the project I have to copy all those additional dll files. Is there a way to avoid this and embed the library into the output .exe?

While merging everything is possible (check ILMerge), I don't recommend it, it's not worth the hassle, because:

If you have to manually copy things around to deploy, you're doing it wrong. You should create a script or an installer (depending on the project type and what you have to do) to move the deployed application around as a whole.

mohabbati
  • 1,162
  • 1
  • 13
  • 31
Albireo
  • 10,977
  • 13
  • 62
  • 96
  • Thanks, that solves the question of handling 3rd party libraries. but what is best practice with regards to internally developed libraries accessed by multiple projects? And also, the question of embedding the libraries or is that not really a done thing? – Dan Dec 17 '15 at 09:46
  • @Dan I've added the missing sections. – Albireo Dec 17 '15 at 10:01
  • It looks like setting up a *remote feed* NuGet server requires IIS which requires Windows Server which I don't think we have... I am right in those assumptions? – Dan Dec 17 '15 at 14:31
  • A NuGet feed is an OData endpoint. Anything that exposes an OData endpoint and adheres to the schema can be a feed. – Albireo Dec 17 '15 at 15:11
  • I think I'm almost there with NuGet. I've set up a server with TeamCity and I was able to install my library as a package. When I push changes to my libraries repo then I see that TeamCity does automatically pull the changes and make a new build and package. However, now when I build a project that uses that package, I don't see the changes come through (I also tried pulling but it said it was up to date). Is there a step that I am missing at the end? Do I need to (can I?) manually tell NuGet to update my package? – Dan Dec 18 '15 at 13:24
  • OK I can manually update it. But the TeamCity server is running as a localhost, so now what happens if someone else want to include the library in one of their projects. They won't have access to this NuGet server as it's running off my machine :( – Dan Dec 18 '15 at 13:52
  • Indeed! I too fail to understand why Microsoft thought it would be a good idea to mislead us all by displaying an absolute path name on the property sheet for project references! This just helps preserve messiness which prevents repeatable, predictable, reliable builds, based on source-code control as the single source of the truth. – Rich Stewart Jul 25 '17 at 18:26
  • btw - it turned out that the solution to this was something simple like just adding the assembly as another project in my solution. I think I confused everyone by the way I was asking the question. If this makes sense to you, maybe add it to your answer? – Dan Dec 21 '17 at 18:09