Where do you put your 3rd party libraries? - c#

I've got a bunch of .dll assemblies, such as HtmlAgilityPack and MoreLinq. Where am I supposed to put these files? I usually toss them somewhere in my Projects folder, but then I'm always digging around for them. Is there a standard place to put them?

There's no standard place to put them, but make sure you:
Put them in one place
Include them in source control.
I put all my required dll's in a top level directory in my solution called "Dependencies", parallel to the project folders. I have them in source control such that when new developers check out the solution, it all compiles and works right off. It's the only way to go.
I include only the .dll files absolutely needed. This keeps it light, which is good, but then when I find some other part of MVC Contrib or whatever that I need, I have to go find the unzipped directory, which might not even be on my computer! Others put entire library directories (readme.txt and all) as part of their source control linked to the solution. This ensures you and future developers will have everything they need, but adds a little dead weight. Either is a good strategy.

Having a "Lib" folder at the same level as source projects is a common way.
To be honest, it's not the dependencies my projects have that I find hard to manage, it's the dependencies the dependencies have. I'd just like to mention NHibernate, Castle Windsor and the various Castle Windsor Facilities in particular. Getting all of those to play together on my last project cost me a lot of time.
For open source projects, I also like to have the source code handy because sometimes its useful to debug into the source code. (And sometimes because the documentation is so poor, you have to read the source code to find out how it works). I've seen VS projects arranged so that the project references the DLL yet at the same time, VS knows where to find the source code, as I write I can't quite remember how to do that.
So, a Lib folder for DLLs works for me; I often call it "Shared Dependencies".
As for open-source source code, I don't have a standard way to version that because each project is structured differently and has a different build process. I don't like to tinker with the open-source project structure or build method because then, I take responsibility for it. If for some reason, it won't build, or builds incorrectly, or produces a faulty DLL, the cause would be exceedingly difficult to track down, and I'd have to get deep into troubleshooting all of that which I dont care about at all.

In a folder UNDER your solution directory, e.g. "external" or "library". That way your continuous integration system (or other team members) can do a pull of one root from your source control system and have everything they need.
In SVN, use svn:externals to pull that directory from a different root so you can easily share library DLLS (and library projects) between solutions.

In the office we have a share on the network for referenced asseblies. These could be 3rd party or assemblies of our own that could be shared between projects.
I also, don't like the idea of putting the dll files in source control. If all the developers have access to the share all will work fine.

The visual studio directory in My Documents seems like a logical place to put them. I don't know if it's the best or anything wrong with it but at least all the libraries are found in one place.
%USERPROFILE%\My Documents\Visual Studio XXXX\Libraries

At my company we place all our shared DLL assemblies onto a network drive in a folder called Assemblies. From there, we use SyncToy to mirror changes between that folder and a folder on our local development machines (in my case C:\Assemblies with subfolders for different versions or useful third party assemblies). Using the "Reference Paths" feature of Visual Studio projects makes it very easy to select different assembly versions based only on locations.
For projects at home, I would definitely go with the idea mentioned by Jeff M of placing them in the Visual Studio folder under My Documents.

I don't have a hard and fast rule on the location. However, I would encourage consistency!
For example, I needed to to this for a small tool I'm writing for a client at the moment, so I checked their other code bases in Bitbucket which seemed to use a dependencies folder in the solution folder (alongside the other projects), so I copied that.

Related

Solution Output Directory

The project that I'm currently working on is being developed by multiple teams where each team is responsible for different part of the project. They all have set up their own C# projects and solutions with configuration settings specific to their own needs. However, now we need to create another, global solution, which will combine and build all projects into the same output directory.
The problem that I have encountered though, is that I have found only one way to make all projects build into the same output directory - I need to modify configurations for all of them. That is what we would like to avoid. We would prefer that all these projects had no knowledge about this "global" solution. Each team must retain possibility to work just with their own sub-solution.
One possible workaround is to create a special configuration for all projects just for this "global" solution, but that could create extra problems since now you have to constantly sync this configuration settings with the regular one, used by that specific team. Last thing we want to do is to spend hours trying to figure out why something doesn't work when building under global solution just because of some check box that developers have checked in their configuration, but forgot to do so in the global configuration.
So, to simplify, we need some sort of output directory setting or post build event that would only be present when building from that global, all-inclusive solution. Is there any way to achieve this without changing something in projects configurations?
Update 1
Some extra details I guess I need to mention:
We need this global solution to be as close as possible to what the end user gets when he installs our application, since we intend to use it for debugging of the entire application when we need to figure out which part of the application isn't working before sending this bug to the team working on that part.
This means that when building under global solution, the output directory hierarchy should be the same as it would be in Program Files after installation, so that if, for example, we have Program Files/MyApplication/Addins folder which contains all the addins developed by different teams, we need the global solution to copy the binaries from addins projects and place them in the output directory accordingly.
The thing is, the team developing an addin doesn't necessary know that it is an addin and that it should be placed in that folder, so they cannot change their relative output directory to be build/bin/Debug/Addins.
The key here is that team is responsible for a deliverable. That deliverable is a collection of binaries. So the "global" solution ... or "product that uses the deliverables from teams" is interested in ensuring that all of the 'current deliverables' work together. That is, that you have a deliverable from the collaborative effort.
So this begs a few questions. Do the team deliver what they consider to be a 'release'. This may be automatic in the build system. If it builds and all tests pass then publish it.
What you are looking for is a team publishing or promoting a release. The source code is how you got there, the binaries are the result. Each team controls what binaries it considers to be a release (this may be automated by the build system).
Not exactly what you asked, but I hope it is the answer that leads to the right questions to give good results.
One very simple way would be to create the solution. Include all the projects and add a project (or more) to handle the global solution build tasks. The projects in the global solution should then have a reference to the projects they need and then let Visual Studio handle how to get the binaries from each project. They will (under normal circumstances) be copied to the output folder of the build project. So the project added specifically for the global build tasks would have a copy of all the referenced projects
Another way would be to create a global MSBuild script that references the rest of the build scripts. Each project is on it's own a MSBuild script
EDIT
From the comments it would seem that there are two categories of projects. One that needs building and one that does not.
For those that need building reference them as projects in the aggregating project for those that do not require building add them either as references or add the dll as resources.
Using the later change the property of the Build action to None and copy to output directory to Copy if newer
In both cases you now have all dll's in the output directory you can then have a post build action on the aggregating project moving the dlls that should be in a specific folder (ie not in the output folder)
Have a look at the practice of Continuous Integration and the usage of a Build Server with scripted builds. This is an indispensable instrument when developing different parts of an application as a team, and your problems are a great illustration of the reason why.
You've not mentioned if you use a Version Control system. I've found in practise that each developer maintains his/hers/their teams configuration and builds locally on there machine, since you don't check *.suo or *.user files most of the personal configuration only affects the individual team member.
On a completely seperate machine check-out the same code from all repositories and compile the project on the build machine (this can be completely automated). This maintains your build servers independance.
Don't worry about it being a "Solution". You can easily build multiple solutions one after the other.
Since the output path is relative (and probably "bin\Debug") it'll get built wherever you check it out to. If you want all the binaries in the same output folder you could tweak the output path on every configuration to match. Something like "....\bin\Debug" (obviously this affects where the projects get built to on the local machines but it might not matter). That way multiple projects would get built the same target output.
You could also include a seperate setup build on the build server which isn't on each developers local machine to package up the final product.

Referencing a 3rd party assembly which is not located in the root location

I have a Visual Studio 2010 C# project which creates an .exe and this project is using some 3rd party class library.
My project is located in: /MyFramWork/tests/test1
3rd party library is located at: /MyFrameWork/bin/utils/
I am adding the reference to the library by using References->Add Reference->Browse. I can see that in the project file all is fine:
....\bin\utils\log4net.dll
False
I would like to reference the 3rd party library without using the option "Copy Local". However if I don't use the option, the library is not found and I get an exception.
My question is: Is there a way to specify that the 3rd party library should be found at ....\bin\utils. It seems that when the .exe gets build the information from the .csproj gets lost.
By default, .NET apps look for their dependencies in only two places: the EXE directory, and the GAC (Global Assembly Cache).
You have three choices:
You can make sure the dependency gets copied into the same directory as your EXE (this is what Copy Local does). This is the best choice most of the time, which is why it's the default when you reference an assembly that's not already in the GAC.
You can install your dependency into the GAC using gacutil. This might be a good choice if your dependency isn't going to change, is going to be in a different location on every development machine (i.e. if relative paths won't work well), and if you want to use it from many different projects. But it's a major pain if the dependency is still under active development and changing frequently. You'll also need to make sure to put the DLL into the GAC on every computer you deploy your app to.
You can customize the dependency-loading behavior so it looks in other places, as Hans noted in his comment. This is an advanced option and comes with a whole new set of headaches.
Normally, you would just use Copy Local; it's a very sensible default. You should need a fairly compelling reason to do anything different.
Use the <probing> element to specify where the CLR should search for your assemblies. The only restriction is that the assemblies must be located in subdirectories of your application's base directory.
For example, if your application base directory is C:\MyFramework, then you could have your assemblies in C:\MyFramework\bin.
Have a look at this article to learn how the CLR searches for assemblies.
If you need to load assemblies from custom locations, you could try the Assembly.LoadFile Method.
The following links may be useful:
C# - Correct Way to Load Assembly, Find Class and Call Run() Method
http://www.csharp-examples.net/reflection-examples/
It's me Potzon. I am still investigating this incredibly silly problem.
I have been hoping for some elegant solution. I am about to build fairly large framework with lots of assemblies which would be placed inside /Framework/bin/. However I wanted to have some directory structure inside the the directory, for example /bin/utils, /bin/test, /bin/devices/ and so on.
One possible solution that I have found is to define environmental variable DEVPATH (see here http://msdn.microsoft.com/en-us/library/cskzh7h6.aspx) but it turns out that .net4 is not using this variable when an assembly is run independently (outside the visual studio), or at least this is the case for me - I can't make it work.
It seems that the solution to put all the assemblies inside the /bin directory without using sub-directories is the best. I think I will give up and just do it this way.

What is the recommendation for adding a library reference in a project?

When I need to add a reference towards a library, I've always been told to use the "add existing project" method, and referencing the project itself inside my solution.
But here in my new company, the use another method. They have a server which holds the compiled dll's, and keep versions of them so they can reference older versions when a change is too important to refactor older apps.
While I find this system really complicated (I guess there is a lot of work if a program pointing an older version of the dll is updated and needs some changes in this dll), they seem to find it pretty convenient.
What are the best practices for this? Linking the dll directly? Linking the project? And why? Any information is welcome!
Thanks in advance !
I usually take a copy of the compiled dll (if the source project is not available or if I don't need the source) and put it in a folder inside my solution, and then reference that. I check it in to source control along with my project.
I am of the opinion that you should be able to check out a project and build it directly from source control without having to go hunting dlls etc.
The Add existing project method is useful when you want to reference a library project which is develop side by side and you want to test/use it's types and methods and this (Add existing project) method will not be used to add the reference of pre-compiled (dll) files.
Read Project Reference (MSDN) article.
You would include it as a Project when you want to simultaneously work on the library. And that would happen mostly for small(ish) libs that will be distributed with your program (bin folder).
When an assembly is (going to be) installed in the GAC, and thus has its own release cycle, it makes more sense to reference the binary only.
Several combination of the above are possible too.
Adding Compiled dlls is mainly when the code is more or less locked (Architecture level code ) which you hardly ever changes
eg
1) communication layer(remoting/wcf)
2) Generic Gui layer (Wizards/dialog boxes)
3) Security layer (azman stuff)
you only need to change when your product is going to another direction say it uses to use .net remoting as communication now it will be using WCF
Using projects as reference when you are frequently changes referenced projects
also Visual studio works out nicely order of building the projects.
Although your company's approach is probably not very common among Microsoft developers, it is used rather successfully in the Java world. In the long run it is probably better controlled than any alternative, but without a fair amount of support scripts/programs (which, for instance, update projects/solutions automatically when needed) it can easily become unmanageable. In the Java world it is directly supported by tools such as Maven.

Moving projects files in a .NET project

It's not code-related but IDE related. I'm working on a .NET solution with about 35 different projects. These projects need to be re-organized into a new folder structure. Why? Because about 10 of those will be removed and the rest will be divided in more logical units.
One way to do this is by creating a new solution, Drag&Drop the projects into a new folder tree within the Windows explorer and then just add them to the new solution.
To be honest, that sounds dumb!
Is there a way to just move projects into different folders from within the IDE? I've tried to "save as" the projects but the IDE won't accept a different folder.
It's irritating but because there have been a few wrong choices in folder names, I'm now stuck with those names.
Example: Right now I have a project main folder which contains child folders named "Client", "Server", "Business", "Database" and whatever more. Within those child folders, there are more child folders, each a three-digit number. Within each numbered folder there's a project which is named in some logical way, like Company.Business.Customers with additional logic within this project.
The problem is that not all projects now follow this naming convention and I consider it obsolete.
A project like Company.Business.Customers should just be in a folder named Company.Business.Customers in the project root so it's easier to recognize. The name already makes it clear that it's a business class for this project. The clear division within client classes, business classes and whatever more just needs to be arranged within the solution, but I want to flatten the file structure. (And remove some obsolete projects.) Basically, I'm not refactoring, I'm just cleaning up.
VS2008 doesn't seem to have such an option, though...
Fire up notepad.exe and open the .sln file. And start Windows Explorer, navigate to the solution directory. Observe how the .sln file content matches the solution structure. Edit the entries, make the corresponding change with Explorer. Backup first.
I don't think there's an easy answer here. Your main problem is going to be that Visual Studio (or .NET) doesn't care if you have classes that belong to a different root namespace sitting in a project.
So if you have a project called Project.BusinessObjects and another project called Project.DataObjects there is nothing stopping you from putting a class called Project.BusinessObjects.User into the Project.DataObjects project.
I don't know of any way of doing all of this without a lot of manual work. Resharper will help quite a bit if you use the 'namespace rename' feature, but you're still gonna end up with a lot of grunt work.
Also, be VERY wary of doing this in conjunction with version control systems. You have to know your version control system really well to know how it's going to react to such major refactoring.
Other than that, what you are describing doing is not all that difficult. You do have to edit the solution files and maybe the project files by hand, and you might need to remove a project from a solution and add it again when it's under the right directory.
I would make a backup, and then refactor away. I think it is a mistake to think that you can do everything you need from the IDE, though. And if you do what you describe from the IDE in a source control system that uses the old Visual SourceSafe API, you will certianly (guaranteed) mess up your bindings, that API is just not made for moving (or renaming, for that matter) files around in the way you describe. The best way to do this under that scenario is to remove all source control bindings and then re-add the reorganized solution back in.
It's not that difficult, you just have to prepare (do a backup) and experiment until you get it right.
I don't think there's any way to do this from within Visual Studio, and as #gmagana points out it's going to be very difficult to do if the files are under version control.
However, it is possible to do it manually.
Start by creating the new, desired folder structure - ignore the .csproj files and solution files for now, and more the .cs files you're interested in into the new structure.
Now, fire up Visual Studio, and create a new, empty project. If you have different types of projects, you might want to create one new, empty project for each type. This will leave you with an empty .csproj file, and a .sln file with just one project.
Copy the empty project file to where they're needed, and rename them as needed. You can edit them and change the Assembly name and default namespace if you want, or wait until you're done and change the settings with Visual Studio.
Finally, edit the .sln file, and remove the Project section. Copy the empty .sln file to where you want it, and open it up in Visual Studio. Now go and add each of your existing projects to the new solution.
Within each project, click the "show all" button, and start including all the files you've copied into the project structure. Resolve missing dependencies, change the namespaces and assembly names for the project, and make sure that the code files don't specify a namespace you don't want. Repeat until done.
Once you get the new solution to build, it will be helpful to open up the DLLs in Reflector in order to ensure that you haven't missed any namespace declarations in the code file - if you're trying to get to a point where there's a 1-1 correspondence between the DLL and the namespace, or even ensuring that no namespaces are split between DLLs, Reflector is your friend.
Good luck.
I've used the following solution to solve my problem:
I started with a new, empty solution in a new folder.
For every project that needed to be moved, I used the Windows explorer to create a child folder in the solution folder, this time with the proper name.
I copied the projects from their original location to their new folders.
I added all the (moved) existing projects from their new locations.
In the Solution Manager, I renamed the projects to a better name.
I fixed the project properties and other settings for all projects.
This did clean up the whole project quite nicely. I then added the whole project to Vault (Version Control System) and once it was in the VSS, I deleted the folder again (actually, just renamed it first) and retrieved it back from the VSS system so any obsolete binaries and other garbage was gone too.
It's a lot of work, but the result turned out exactly what it needed.

How do you package external libraries in your .Net projects?

A lot of my projects contain the Castle/NHibernate/Rhino-Tools stack. What's confusing about this is that Castle depends on some NHibernate libraries, NHibernate depends on some Castle libraries, and Rhino-Tools depends on both.
I've built all three projects on my machine, but I feel that copying the NHibernate/Castle libraries is a bit redundant since I built Rhino-Tools using the resulting libraries from my NHibernate and Castle builds.
Right now, I include all projects in seperate folders in my /thirdparty/libs folder in my project tree. Should I simply just have /thirdparty/libs/rhino-tools in my project and use the Castle/NHibernate libs from there? That would seem to make logical sense in not duplicating files, but I also like having each project in it's own distinct folder.
What are your views on this?
This is one of the problems that we're trying to tackle in the Refix open source project on CodePlex.
The idea is that Refix will parse all the projects in your solution, and before your project compiles, copy the necessary binaries from a single local repository on your machine into a folder within the solution tree and point the projects at them. This way, there's no need to commit the binaries. Your local Refix repository will pull binaries from a remote one (we're setting one up at repo.refixcentral.com), and you can set up an intermediate one for your team/department/company that can hold any additional software not held centrally.
It will also try to resolve conflicting version numbers - Visual Studio can be too forgiving of mismatched component version numbers, leading to solutions that compile but fall over at run time when they fail to load a dependency because two different versions would be needed.
So to answer the question "how do you package external libraries in your .Net projects", our vision is that you don't - you just include a Refix step in your build script, and let it worry about it for you.
I use a folder for each, which seems to be the convention.
Does it really make a difference if you're copying them?
What if you want to switch one out? Let's say you go with a new O/R mapper. It will be much easier to just delete the NHibernate folder than to selectively delete DLLs in your Rhino-Tools folder.
Take this to it's logical conclusion and you won't have any folder organization in your lib folder since everything uses log4net :)
Add additional probing paths to your app.config files to locate the dependency dlls. This way your can get away with having just one copy of everything you want. Though there are some quirks to using this feature (you must create the folder structure in a certain way). Look here for more details on the tag.
I will definetly recommend having a thirdparty or vendor folder in each of your project trees. If you find it annoying to have 32 copies of the rhino-tools package, you can have a single copy of it in your code repository, and do external references to it in your project tree.
Lets say you are using SVN, you can make a repository called "thirdparty libs" and in this have versioned copies of the libs. You then make an external property on your "thirdparty"-folder in your project tree which then in turn automaticly will do a check out of your centralized thirdparty libs. This way you for instance only have to update in one place if a security or a bugfix comes out, but each project is still in command of choosing which thirdparty libs, and which versions to use.
About the deps internally in thirdparty libs, i wouldn't mind those. The first time you compile your project, and some of the libs arent copied to your bin-folder because of implicit dependencies you can add an external attribute into your bin-folder, which will then automaticly check out the missing libs. That way you still only have to update your thirdparty libs in one place.

Categories