Best practice for storing and referencing DLL libraries? - dll

Often times a developer on my team will create a new Visual Studio project and reference a DLL somewhere on their local machine (e.g., C:\mydlls\homersimpson\test.dll). Then, when I get the project from the source control repository, I cannot build the project because I do not have the referenced dll in the exact same location on my machine.
What is the best practice for storing and referencing shared libraries?

I typically create a lib folder in my project, where I put the referenced dll's. Then I point the reference to the dll in the lib folder. This way, every developer can build the project after retrieving from source control.
If it's a project that was built in house, you could also add that project to your solution.

If the assembly is not in the GAC, create a directory called dependencies and add all assemblies there. The folder and the assemblies are added to source control. The rule is that given any project in source control, all that is required to build is to do a checkout and build the project (or run some tool that is also checked into the project).
If you add a folder to the solution and add the assemblies to the solution folder, this also provides a visual cue to the devs that indicates what external dependencies are present... all dependencies are in that directory. Relative paths ensure that Visual Studio can locate the references without a problem.
For large solutions, with 20+ projects, this makes life much easier!

Best practice I would expect would have Your SC repository include and enforce the relative locations of referenced objects for you (usually via a shared path), so you aren't dealing with this issue directly. The original developer should check in this information.

If you check in the actual DLLs into source control, then you can reference them by relative path and all developers will automatically get any dependencies when they next update the project.
Adding a DLL reference by full path would be a developer error just as adding a source file by full path would be an error.

Rule of thumb: If the project isn't a part of the solution, reference released dlls from a source controlled /binshare or /lib directory that is under your solution's source control tree. All external dependencies should have versioned DLLs that go in this /binshare directory.
I understand what your co-worker is doing in regards to convenience. However, that developer's approach is diametrically opposed to proper configuration/build management.
Example: If you use the MS Data Application Block as a dependency in your application, you should reference a properly released binary, instead of getting latest from MS's dev source trunk.

I think this approach is quite the opposite of what I would consider best practice. I think it would be a much better approach to keep the third party binaries out of the source repository and reference them through something like a Maven repository in your build process. Putting the dlls in the source repository unnecessarily bloats the contents of the repository and results in gets of projects taking considerably longer then necessary. It also makes the independent management of the third party binaries' versions obfuscated by not referencing the version by name but rather implied by referencing the dll of a particular version stored in the projects lib folder.

Why not set up a private NuGet-feed? This way, there is only a single copy of a dependency (the NuGet repository) and multiple projects can reference it. Multiple versions of the dependency can coexist, and each project can reference a different version, if necessary. Also, TFS Build can restore the packages at build time.
Configuring VS: https://www.visualstudio.com/en-us/docs/package/nuget/consume

Related

How to version a VxWorks Workbench Project

I am attempting to stand up a VxWorks Workbench version 4.5.2 project into a CM system but am running into issues. I have just started learning VxWorks Workbench. I have searched a bit on how others have done this and I came across two solutions:
Make the project path relative in a sub-directory in the WindRiver home directory.
Do not version Workbench project files and just version my source code. Every client must re-create the Workbench project on their local machine.
The first solution would be ok but I have not been able to make it work. There seems to be some registry (Windows 10) or some path stored elsewhere for Workbench related workspace locations but the end result is the project is not loaded.
The second solution would be a last resort that I would prefer not to do as there are many steps to re-creating a project on a local machine making it tedious and error prone. Does anyone have experience versioning Workbench 4 projects into CM and can share possible solutions?
This can be complicated, and it very much depends on what project type you are talking about.
For DKMs, RTPs, Static and Shared Library projects, you need to version these project files:
.wrproject
.wrmakefile
.cproject
.project
Other project types will have these, but also some additional files that are required to recreate the project, for instance VIP projects also have a <projectname>.wpj file. A conclusive list is too long for this answer however.
You do not need to version the automatically generated Makefile , nor do you need to version the automatically generated build subfolders.
My advice is to store the projects along side your code. I personally prefer to store my projects outside of my workspace, and they should certainly not be stored anywhere in your Windriver installation folder.
I tend to use a structure like this:
c:\gitrepositorys\CuriousCamel\Source\
dkmProject1
.wrproject
.project
.wrmakefile
.cproject
dkm.c
dkmProject2
dkmProject3
vipProject
etc.
The above are all versioned. In terms of the actual Workbench Workspace, I tend to create it in c:\gitrepositorys\CuriousCamel\Workspace and this is explicitly not versioned - I create it fresh for each clone, and often delete and recreate when I switch branch.
Existing projects can be imported into the workspace using the import wizard (using the General->Existing Projects from Filesystem option). When you create a new project, just make sure you choose the "Create Project in external location" option, and select wherever you have chosen to store projects.

VSTS build project with reference to other solution

I have a repository that contains two solutions. One solution (in this case solution A) for a web project that has a reference to a project in the second solution (in this case solution B) (in the same repository).
When I build the web project in VSTS I pull the repository, build solution B, and then build solution B.
Build solution B work, but, the build of solution A is failed cause the reference dll of the project in solution B didn't found
You have a few options:
1) Use project references. You don't need to depend on an assembly.
2) Use NuGet packages -- the shared piece is built via a CI process, turned into a NuGet package, and then published to a Packages feed. The dependent projects can reference the NuGet package and restore an appropriate version on build.
Which approach you should take depends on a lot of factors. If you're not worried about versioning, just use project references.
As Daniel said that it’s better to use NuGet packages.
Regarding reference the assembly file directly, refer to these steps:
Open your web project file through Notepad
Find the related reference and check Hintpath value, should be relative path.
Add Copy files task to your build definition (Before build solution A task) to copy corresponding assembly files to corresponding folder (per to that relative path)

Best way to access DLLs during development

I'm creating a development environment that should be easy to install on new systems. Therefore I created library packages (OpenCV, boost, Qt etc) all placed in a single folder (environment_folder) which is accessed by an environment variable by Visual Studio projects/solutions (so for a single compiler the whole folder can be copied and only the variable has to be set).
Now to execute the binary it needs access to the DLLs of those libraries.
I typically copy all needed DLLs to the binary directory, but that's neither nice nor pratical.
Another way would be to add all the libraries' pathes to the PATH variable, but that's a lot of work to perform while/after installing the library packages, so I would like to avoid it. Additionally it is error-prone when testing new versions of libraries for example.
A third way that comes in my mind would be to copy all the DLLs to a single package_bin folder, so only a single path has to be added to the PATH variable (which is additonally relative to the environment_folder), but I don't like that idea.
Is there any better way to do it?

Include RIA Services in Solution without usual installation

I want to use WCF RIA Services without need to install this. My idea is just to reference the libraries:
Microsoft.ServiceModel.DomainServices.Hosting.dll and Microsoft.ServiceModel.DomainServices.Tools.dll
in my Solution Libs folder.
This avoid overhead for devs and even for deployment.
This solution creates some evil hide monster? I forgetting something?
*I tried this and, well, "It works in my machine" until now.
If you reference DLL´s that are only on your development machine, make sure your reference doesn´t point to the Globsal Assembly Cache. Otherwise the other developers can´t find the reference.
Also selecting ´Copy Local´ for the references will make sure they are copied to the bin directory so you can deploy the solution with the necessary dll´s included.
I would suggest storing the actual dll files in a References folder in the root of your project. Then add them to your project through visual studio. Once you've done that add the hintpath node to the actual project file for each reference, which will tell VS where to look for the file. This method works great especially if you are working with multiple projects because then you dont have to copy the dll files to each bin directory.

MSBuild overwriting dependencies

Ok, so I've got a somewhat complicated problem with my build environment that I'm trying to deal with.
I have a solution file that contains multiple C# projects which is built by a NAnt script calling MSBuild - passing MSBuild the name of the solution file and a path to copy the binaries to. This is because I want my automated build environment (CruiseControl.Net) to create a folder named after the revision of each build - this way I can easily go back to previous binaries for any reason.
So idealy I have a folder layout like this
c:\build\nightly\rev1
c:\build\nightly\rev2
c:\build\nightly\rev3
...
c:\build\nightly\rev10
etc.
The problem that's arisen is I recently added the latest version of the Unity IoC container to my project, checking it directly out of MS's online SVN repository. What's happening is I have a Silverlight 3 project that references the Silverlight version of Unity but I also have other projects (namely my Unit testing project) that reference the standard (non-Silverlight) version of Unity.
So what happens is since MSBuild is dumping everything into one single folder the Silverlight version of the Unity assembly is overwriting the non-Silverlight version because they have the exact same assembly file name.
Then when CruistControl runs my unit tests they fail because they don't have the proper dependencies available anymore (they try to load the Silverlight specific Unity assembly which obviously doesn't work).
So what I want to do is:
keep my desired output directory
structure (folder\revision)
I don't want to have to manually edit
every single proj file I have as this
is error prone when adding new
projects to the solution
Idealy I would like MSBuild to put everything into a folder structure similar to this:
nightly\revision1\project1
nightly\revision1\project2
nightly\revision1\project3
...
nightly\revision2\project1
nightly\revision2\project2
nightly\revision2\project3
etc
I can't modify the Unity project to give it a different file name because it comes from another SVN repository I cannot commit changes to. I found a similar question posted here and the suggested solution was to use a "master" MSBuild file that used a custom task to extract all the project file names out of the solution then loop over each one building them. I tried that but it doesn't build them in the order of their dependencies, so it fails for my project.
Help?
Firstly I would always have the build server delete the old working copy and check out a fresh copy to avoid any problems with stale artifacts from the previous build.
Next I would have nant or msbuild build the solutions as before with the artifacts from each build going to their local working output folders.
After that I'd move the artifacts from their working paths to their output paths, this shouldn't require digging through the project files since you can just tell msbuild/nant to copy working\project1\bin\release\**\*.* to artifacts\project1\.
The script that does this should ideally be stored along with the source with the main file, e.g. build.nant or build.proj in top level of the trunk.
For third party libraries I would simple include the DLLs directory in your repository. Nothing worse than writing some code and having a third party dependency break your build because of changes on their end.
Simply document the versions of the libraries you are using, and if you must update them, you'll have a better sense of what breaks the build before you even check it in.
Also, doesn't CC.Net automatically handle the providing of releases based on revision? I'm using TeamCity and it keeps a copy of the artifacts of every build.
I highly recommend reading JP Boodhoo's Automating Builds with NAnt blog series. That's been my starting point and have made lots of changes for my own taste. I also highly recommend checking out the builds of many open sources projects for examples. I've learned a lot from the builds of the Castle/Nhibernate/Rhino-Tools stack.