Naming convention for Visual Studio solutions and projects - visual-studio

We were thinking about organizing our BIG project this way:
\trunk
[CompanyName]
[Product1]
[Project1]
CompanyName.Product1.Project1.csproj
[Project2]
CompanyName.Product1.Project2.csproj
CompanyName.Product1.sln
[Product2]
We were trying to follow Microsoft's recommendation that namespace names follow folder structure, but are there any drawbacks for making it this way?
What is the naming convention for solutions and projects that you apply?

That looks pretty good if you ask me. Especially naming your projects by their full name including full name space part. I've found this helpful when there are numerous projects, especially if there happens to be similar projects across different products.
How and whether you split on product and project (where I assume project is more like an application than a solution project) is very much down to the size of your organisation, it's make-up and your preferences.

An alternative that I've used is to have all my solution files in the same directory.
\trunk
[CompanyName]
CompanyName.Product1.sln
CompanyName.Product2.sln
[Product1]
[Project1]
CompanyName.Product1.Project1.csproj
[Project2]
CompanyName.Product1.Project2.csproj
[Product2]
[Project3]
CompanyName.Product2.Project3.csproj

With respect to file names - I prefer that my project file name match the output assembly name because it makes it much easier to know what produces what. Doing a directory listing is much faster than searching the csproj files in a tree for the one that produces the assembly I care about.
I don't get worked up about solution files because they don't influence our build environment so I end up making my own to have the exact scope I want (and the specific per-solution items, like test metadata, that I want).
With respect to folder structure - I don't worry too much if the folders leading down the project files match the namespaces. I want my code to sit on disk in a way that makes the most sense for the project. Sometimes this means the test code and product code are in sibling directories - sometimes it means they are much further apart. Sometimes there is a namespace that is contributed to by multiple teams (not advocating that design, just a reality) - but those teams want to life in their own folders for whatever reason.
Don't forget the importance of version control branching strategies in your overall project design. The Company and Product boundaries may be branches and therefore would not necessarily need to represented as directories on disk.
Don't let this be a source of analysis paralysis though. Make a reasonable choice. Use version control. You can always change later if you are wrong.

Looks like taken from the school book. That's usually how my solutions get set up, and I have found it to work quite well over the years.

Looks good to me.
It's a point to note that by default, the default namespace in a Visual Studio project is just the project name. Surely that indicates that naming your projects like your namespaces is "the Visual Studio Way".
Solutions are most naturally named after the product/project. Like you indicate.

I consider this is better
\trunk
[CompanyName]
[Product1]
CompanyName.Product1.sln
[Main] --Optional
CompanyName.Product1.csproj
[Project1]
CompanyName.Product1.Project1.csproj
[Project2]
CompanyName.Product1.Project2.csproj
[Product2]
CompanyName.Product2.sln
[Main] --Optional
CompanyName.Product2.csproj
[Project1]
CompanyName.Product2.Project3.csproj
[Project2]
CompanyName.Product2.Project2.csproj
[Project3]
CompanyName.Product2.Project2.csproj
Why? Because when you get the code from repository you get, by example, "Product1" directory, it contains all you need to work. The [Main] directory contains the default base namespace, usually the exe or main project. It is optional.

Downsides to naming projects / solutions with name spacing are that:
1. Your solution project will not build due to Windows ( my version and previous ) imposing a max limits on the length of path ( not a problem on <cough><cough> mac ). Two solutions are:
1. Changing an operating system setting.
2. Configure build to shorten path.
2. Various apps important to you like say, SourceTree, may encounter problems. I figure this is due to the assumption as to filepath length. This problem is detailed in this Stack Overflow question:Filename too long in Git for Windows
Regarding Problem (1)
Visual Studio might warn you
I don't yet know how to enact (2).
If you choose (1), then this will have an affect on your downstream environments: build OS, dev OS, qa build OS, qa OS, production OS as you will either need to make changes to the OS. Stack overflow question with answer describing change to operating system: Could not write lines to file "obj\Debug\net5.0\SolutionName.GeneratedMSBuildEditorConfig.editorconfig exceeds the OS max path limit
Code MSB3491
https://www.google.com/search?q=Code+MSB3491+max+path+limit
Could not write lines to file "obj\Debug\net5.0\------------my namespace------------..GeneratedMSBuildEditorConfig.editorconfig". Path: obj\Debug\net5.0\------------my namespace------------.GeneratedMSBuildEditorConfig.editorconfig exceeds the OS max path limit. The fully qualified file name must be less than 260 characters.
-------------my namespace--------------------------------
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn\Microsoft.Managed.Core.targets
Regarding Problem (2)
To fix, possible solutions are:
(1) Tell SourceTree to use the git installed on the system. I only had Atlassian's version of git with which to work.
(2) Tell Atlassian's git to work with long file paths. Run cmd as administrator, then run this command:
c:\Users\{theuser}\AppData\Local\Atlassian\SourceTree\git_local\cmd\git.exe config --system core.longpaths true
If you choose either of these resolutions, then you should expect to make changes to systems / processes down the line from your development machine.

Related

Proper setup for visual studio and SVN

I am wanting to setup a project and potentially an existing project to be SVN version controlled. I am using uberSVN for the svn server. I have installed AnkhSVN for visual studio.
Currently, the team I am working with is using visual source safe and one of the problems we have is when someone adds a reference to a DLL, it modifies the project file as you would expect, but our paths are different between different team members (XP boxes, 7, you get the idea). What I was wanting is making the project file ignored when checking in/out so that we don't mess up the references for everyone else.
Is there a way I can make SVN ignore these files within the plugin? One of the side effects of this is a person would not know if a new file has been added in the project as this modifies the project file. Other than telling everyone "hey, you need to manually add this file to your project," is there a cleaner way of doing it?
If you copy the DLL to a folder inside your VS solution folder before linking to it, I think the project link will be relative not absolute. So you can check the DLL and the updated VS project into your configuration management and everyone should be able to share it.
You should start using virtual paths for development work; that way each team member can keep work-related files at any physical location but the virtual path (the one seen by tools is always the same.
For example, my team does all work under Q:\. My physical source for work is under physical path C:\Work\<project_name> where the project_name part depends on the project. When I want to work on a given project, I map the Q:\ virtual path to the right physical path using
subst q: c:\work\project_name
When I need to switch, I run a similar command. This way there's no need to worry about different paths on different computers. This worked very well for the whole team and eliminated most issues you describe above. The only thing you need to make sure is that everyone always uses the virtual path (Q:), not the physical path when dealing with project-related files. For my team it took about a week to get used to that, after that there were no more problems.
Your project file is an important part of your project so ignoring it in the source control tool will eventually lead to problems. I recommend you don't do it (even if you can).
Edit:
If you have DLL-s in different physical folders on different machines, the best choice is to copy those DLL-s (and their dependencies) to a known location. It's fine that they can't run from there, as long as the compiler finds them.
This known location could be inside your virtual path or a common physical path (if the same DLL-s are needed for multiple projects). You can use Dependency Walker to determine what dependencies you need for native DLL-s and Reflector for .NET DLL-s.
If the size/number of DLL-s is so large that creating a copy is not an option, you can actually tell AnkhSVN to ignore certain versioned files when committing changes. Right-click the file, select Subversion > Move to Change List > ignore-on-commit. After this the file will show up in the commit dialog unselected but you can still commit it if you manually select it.

How can I make the SourcePath property of a file in a Visual Studio Setup and Deployment project (Windows Installer) relative rather than absolute?

I've got a relatively simple project that is under source control (svn), and I wanted to create an installer. I know that I could (should) use WiX, but as I'm new to creating installers I thought it'd be easier to just use the built-in Visual Studio (2010) Setup and Deployment Wizard.
Unfortunately, it seems that files including external (non-project maintained) documentation, configuration files, and "Content" files are added with absolute paths. This, of course, is suboptimal. I searched the web, but found only the same question, without an answer. Another stackoverflow user seems to have asked a similar question, but the only answer, which suggests ClickOnce, seems off-base (I'd like to have an MSI that I distribute not a web-based installation).
Does anyone know how (or whether) this can be fixed?
With VS2005, sometimes the paths stored in the vdproj file were absolutes, and sometimes relatives. In my case, it seemed to be related to whether the files were accessed via the canonical path or not. Here's a concrete example:
Source is on C:\Views\builddir, open solution C:\Views\builddir\solution.sln and add files from C:\Views\builddir\.. and VS2005 would add relative paths into the vdproj file. However, if you map that builddir to a letter drive, for example, make a subst from C:\Views\builddir to s:, open the solution via S:\solution.sln, and then add files by navigating to S:\.., VS2005 would insert absolute paths into the vdproj files. Whether VS2005 displayed paths as absolutes or relatives had no relation to what it stored in the vdproj files.
So, it may well be that the problem comes down to what path you're using to open that solution.. opening \\server\shareddir\solution.sln might get different behavior than mapping \\server\shareddir to W: and opening w:\solution.sln.
You can always add the files, then use a text editor (e.g. notepad) to change the absolute paths in the vdproj file to relative ones. You'll be fine until you change that project again.
MS doesn't seem to really fix minor bugs like this so much as rewrite the code to introduce an entirely different set of bugs, so VS2010 might still act this way.
FYI, why would one want to map an absolute path to your builddir? It was a holdover from the bad old days when VS didn't do anything correct with relative paths.
As tzerb mentioned, the main source of confusion might be that paths show up as absolute under the property window inside VS, but when you look into the actual VDPROJ file you should see the paths show up as relative. However, as patbob mentioned, I believe the paths ARE stored as absolute when they come from a different letter drive.
It might be easier now but when you start bumping into the limitations of the tool it's going to get real hard. Let's not even talk about the bad practices it will encourage which could end up being real hard for the poor end user installing your product. You've got Visual Studio 2010 so InstallShield LE ( free ) would be a better choice.
Otherwise, to answer your question, it will only use absolute paths if it can't caculate a relative path. ( for example c:\foo\foo.vdproj consuming d:\foo.txt consuming c:\test\foo.txt should automatically be ....\test\foo.txt )
BTW, if you decide to check out WiX and want some "easy" check out my IsWiX project on CodePlex. I'm trying to bridge the feature gap between InstallShield and WiX.

Should a .sln be committed to source control?

Is it a best practice to commit a .sln file to source control? When is it appropriate or inappropriate to do so?
Update
There were several good points made in the answers. Thanks for the responses!
I think it's clear from the other answers that solution files are useful and should be committed, even if they're not used for official builds. They're handy to have for anyone using Visual Studio features like Go To Definition/Declaration.
By default, they don't contain absolute paths or any other machine-specific artifacts. (Unfortunately, some add-in tools don't properly maintain this property, for instance, AMD CodeAnalyst.) If you're careful to use relative paths in your project files (both C++ and C#), they'll be machine-independent too.
Probably the more useful question is: what files should you exclude? Here's the content of my .gitignore file for my VS 2008 projects:
*.suo
*.user
*.ncb
Debug/
Release/
CodeAnalyst/
(The last entry is just for the AMD CodeAnalyst profiler.)
For VS 2010, you should also exclude the following:
ipch/
*.sdf
*.opensdf
Yes -- I think it's always appropriate. User specific settings are in other files.
Yes you should do this. A solution file contains only information about the overall structure of your solution. The information is global to the solution and is likely common to all developers in your project.
It doesn't contain any user specific settings.
You should definitely have it. Beside the reasons other people mentioned, it's needed to make one step build of the whole projects possible.
I generally agree that solution files should be checked in, however, at the company I work for we have done something different. We have a fairly large repository and developers work on different parts of the system from time to time. To support the way we work we would either have one big solution file or several smaller. Both of these have a few shortcomings and require manual work on the developers part. To avoid this, we have made a plug-in that handles all that.
The plug-in let each developer check out a subset of the source tree to work on simply by selecting the relevant projects from the repository. The plugin then generates a solution file and modifies project files on the fly for the given solution. It also handles references. In other words, all the developer has to do is to select the appropriate projects and then the necessary files are generated/modified. This also allows us to customize various other settings to ensure company standards.
Additionally we use the plug-in to support various check-in policies, which generally prevents users from submitting faulty/non-compliant code to the repository.
Yes, things you should commit are:
solution (*.sln),
project files,
all source files,
app config files
build scripts
Things you should not commit are:
solution user options (.suo) files,
build generated files (e.g. using a build script) [Edit:] - only if all necessary build scripts and tools are available under version control (to ensure builds are authentic in cvs history)
Regarding other automatically generated files, there is a separate thread.
Yes, it should be part of the source control.
When ever you add/remove projects from your application, .sln would get updated and it would be good to have it under source control. It would allow you to pull out your application code 2 versions back and directly do a build (if at all required).
Yes, you always want to include the .sln file, it includes the links to all the projects that are in the solution.
Under most circumstances, it's a good idea to commit .sln files to source control.
If your .sln files are generated by another tool (such as CMake) then it's probably inappropriate to put them into source control.
We do because it keeps everything in sync. All the necessary projects are located together, and no one has to worry about missing one. Our build server (Ant Hill Pro) also uses the sln to figure which projects to build for a release.
We usually put all of our solutions files in a solutions directory. This way we separate the solution from the code a little bit, and it's easier to pick out the project I need to work on.
The only case where you would even considder not storing it in source control would be if you had a large solution with many projects which was in source control, and you wanted to create a small solution with some of the projects from the main solution for some private transient requirement.
Yes - Everything used to generate your product should be in source control.
We keep or solution files in TFS Version Control. But since or main solution is really large, most developers have a personal solution containing only what they need. The main solution file is mostly used by the build server.
.slns are the only thing we haven't had problems with in tfs!

MSBuild directory structure limit workarounds

Does anyone have a method to overcome the 260 character limit of the MSBuild tool for building Visual Studio projects and solutions from the command line? I'm trying to get the build automated using CruiseControl (CruiseControl.NET isn't an option, so I'm trying to tie it into normal ant scripts) and I keep on running into problems with the length of the paths. To clarify, the problem is in the length of paths of projects referenced in the solution file, as the tool doesn't collapse paths down properly :(
I've also tried using DevEnv which sometimes works and sometimes throws an exception, which isn't good for an automated build on a separate machine. So please don't suggest using this as a replacement.
And to top it all, the project builds fine when using Visual Studio through the normal IDE.
It seems that it is limitation of the MSBuild. We had the same problem, and in the end, we had to get paths shortened, because did not find any other solution that worked properly.
The SUBST command stills seems to exist so remapping the root of your build folder to a drive letter may save some characters if Judah Himango's solution is no good.
I solved similar issue by adjusting CSPROJ-file:
<BaseIntermediateOutputPath>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..\..\..\Intermediate\$(AssemblyName)_$(ProjectGuid)\'))</BaseIntermediateOutputPath>
As the result during compilation CSC.EXE receives full path instead of relative one.
Thanks to harrydev for clue on how CSC.EXE operates with the paths.
There are two kinds of long path problems relevant to build. One is paths that aren't really too long, but have lots of "..\" in them. Typically, these are references' HintPath values. MSBuild should normalize these paths down to below the max limit, so that they work.
The other kind of path is just plain too long. Sorry, but these just won't work. After looking at it a fair bit, the problem is that there just isn't sufficient API support for long paths. The BCL team (see their blog) had similar problems. Only some of the Win32 API's support the \?\ format. Arbitrary build tools, and probably 98% of apps out there, don't; and worse would probably behave badly (think of all the buffers sized for MAX_PATH).
We came to the conclusion that until there's a big ecosystem effort to make long paths work, or Windows comes up with some ingenious way to make them work anyway (like the short paths mangling?) long paths just aren't possible for MSBuild to support. Workarounds include subst, as you found; but if your tree just is simply too deep, your only options are to build it in fragments, or to shorten the folder names. Sorry.
Dan/MSBuild
I found the problem to be that when the C# compiler (csc.exe) is called it uses the projects directory path PROJECTDIRECTORY together with the output path OUTPUTPATH by simply appending them as:
PROJECTDIRECTORY+OUTPUTPATH
However, if the OUTPUTPATH is relative i.e. "..\..\Build\ProjectName\AnyCPU_Debug_Bin\" and the project directory is pretty long then the total length is longer than 259 characters since the path will be:
PROJECTPATH+"..\..\Build\ProjectName\AnyCPU_Debug_Bin\"
instead of an absolute path.
If csc.exe would make an absolute path before calling Win32 functions this would work. Since in our case the absolute path length is less than 160 characters.
For some reason the call to csc.exe from visual studio is then different from MSBuild than it is from visual studio. Do not know why.
In any case, the problem can be resolved by changing either or both PROJECTDIRECTORY and/or OUTPUTPATH paths.
Have you tried DOS paths? Or the \\?\ prefix? The .NET BCL team blog has more info.
If the path length is 260, then there is warning resolving reference, for 259 or 261 of this error does not occur. I think there is msbuild bug.
I know there is already an accepted answer, but I had a different problem while using msbuild that gave me the same error output, and led me on a circular wild-goose chase. So, for future googlers, here goes:
We have a batch file that calls msbuild, but as the build machine can build for multiple versions of Visual Studio, each batch file calls vcvarsall.bat before it runs msbuild. This has the nasty side effect of stuffing the path completely full of the same thing over and over again. When it fills up, you get the error shown in the question above: The input line is too long. A simple Google search could make you think your paths are suddenly too long for msbuild.
In my case, it was as simple as killing the session of cmd.exe and restarting, as this reverted the environment variables to their native state.

Structuring projects & dependencies of large winforms applications in C#

UPDATE:
This is one of my most-visited questions, and yet I still haven't really found a satisfactory solution for my project. One idea I read in an answer to another question is to create a tool which can build solutions 'on the fly' for projects that you pick from a list. I have yet to try that though.
How do you structure a very large application?
Multiple smallish projects/assemblies in one big solution?
A few big projects?
One solution per project?
And how do you manage dependencies in the case where you don't have one solution.
Note: I'm looking for advice based on experience, not answers you found on Google (I can do that myself).
I'm currently working on an application which has upward of 80 dlls, each in its own solution. Managing the dependencies is almost a full time job. There is a custom in-house 'source control' with added functionality for copying dependency dlls all over the place. Seems like a sub-optimum solution to me, but is there a better way? Working on a solution with 80 projects would be pretty rough in practice, I fear.
(Context: winforms, not web)
EDIT: (If you think this is a different question, leave me a comment)
It seems to me that there are interdependencies between:
Project/Solution structure for an application
Folder/File structure
Branch structure for source control (if you use branching)
But I have great difficulty separating these out to consider them individually, if that is even possible.
I have asked another related question here.
Source Control
We have 20 or 30 projects being built into 4 or 5 discrete solutions. We are using Subversion for SCM.
1) We have one tree in SVN containing all the projects organised logically by namespace and project name. There is a .sln at the root that will build them all, but that is not a requirement.
2) For each actual solution we have a new trunks folder in SVN with SVN:External references to all the required projects so that they get updated from their locations under the main tree.
3) In each solution is the .sln file plus a few other required files, plus any code that is unique to that solution and not shared across solutions.
Having many smaller projects is a bit of a pain at times (for example the TortoiseSVN update messages get messy with all those external links) but does have the huge advantage that dependancies are not allowed to be circular, so our UI projects depend on the BO projects but the BO projects cannot reference the UI (and nor should they!).
Architecture
We have completely switched over to using MS SCSF and CAB enterprise pattern to manage the way our various projects combine and interact in a Win Forms interface. I am unsure if you have the same problems (multiple modules need to share space in a common forms environment) but if you do then this may well bring some sanity and convention to how you architect and assemble your solutions.
I mention that because SCSF tends to merge BO and UI type functions into the same module, whereas previously we maintained a strict 3 level policy:
FW - Framework code. Code whose function relates to software concerns.
BO - Business Objects. Code whose function relates to problem domain concerns.
UI - Code which relates to the UI.
In that scenario dependancies are strictly UI -> BO -> FW
We have found that we can maintain that structure even while using SCSF generated modules so all is good in the world :-)
To manage dependencies, whatever the number of assemblies/namespaces/projects you have, you can have a glance at the tool NDepend.
Personnaly, I foster few large projects, within one or several solutions if needed. I wrote about my motivations to do so here: Benefit from the C# and VB.NET compilers perf
I think it's quite important that you have a solution that contains all your 80 projects, even if most developers use other solutions most of the time. In my experience, I tend to work with one large solution, but to avoid the pain of rebuilding all the projects each time I hit F5, I go to Solution Explorer, right-click on the projects I'm not interested in right now, and do "Unload Project". That way, the project stays in the solution but it doesn't cost me anything.
Having said that, 80 is a large number. Depending on how well those 80 break down into dicrete subsystems, I might also create other solution files that each contain a meaningful subset. That would save me the effort of lots of right-click/Unload operations. Nevertheless, the fact that you'd have one big solution means there's always a definitive view of their inter-dependencies.
In all the source control systems that I've worked with, their VS integration chooses to put the .sln file in source control, and many don't work properly unless that .sln file is in source control. I find that intriguing, since the .sln file used to be considered a personal thing, rather than a project-wide thing. I think the only kind of .sln file that definitely merits source control is the "one-big-solution" that contains all projects. You can use it for automated builds, for example. As I said, individuals might create their own solutions for convenience, and I'm not against those going into source control, but they're more meaningful to individuals than to the project.
I think the best solution is to break it in to smaller solutions. At the company I currently work for, we have the same problem; 80 projects++ in on solution. What we have done, is to split into several smaller solutions with projects belonging together. Dependent dll's from other projects are built and linked in to the project and checked in to the source control system together with the project. It uses more disk space, but disk is cheap. Doing it this way, we can stay with version 1 of a project until upgrading to version 1.5 is absolutely necessary. You still have the job with adding dll's when deciding to upgrade to a other version of the dll though. There is a project on google code called TreeFrog that shows how to structure the solution and development tree. It doesn't contain mush documentation yet, but I guess you can get a idea of how to do it by looking at the structure.
A method that i've seen work well is having one big solution which contains all the projects, for allowing a project wide build to be tested (No one really used this to build on though as it was too big.), and then having smaller projects for developers to use which had various related projects grouped together.
These did have depencies on other projects but, unless the interfaces changed, or they needed to update the version of the dll they were using, they could continue to use the smaller projects without worrying about everything else.
Thus they could check-in projects while they were working on them, and then pin them (after changing the version number), when other users should start using them.
Finally once or twice a week or even more frequently the entire solution was rebuild using pinned code only, thus checking if the integration was working correctly, and giving testers a good build to test against.
We often found that huge sections of code didn't change frequently, so it was pointless loading it all the time. (When you're working on the smaller projects.)
Another advantage of using this approach is in certain cases we had pieces of functionality which took months to complete, by using the above approach meant this could continue without interrupting other streams of work.
I guess one key criteria for this is not having lots of cross dependencies all over your solutions, if you do, this approach might not be appropriate, if however the dependencies are more limited, then this might be the way to go.
For a couple of systems I've worked on we had different solutions for different components. Each solution had a common Output folder (with Debug and Release sub-folders)
We used project references within a solution and file references between them. Each project used Reference Paths to locate the assemblies from other solutions. We had to manually edit the .csproj.user files to add a $(Configuration) msbuild variable to the reference paths as VS insists on validating the path.
For builds outside of VS I've written msbuild scripts that recursively identify project dependencies, fetch them from subversion and build them.
I gave up on project references (although your macros sound wonderful) for the following reasons:
It wasn't easy to switch between different solutions where sometimes dependency projects existed and sometimes didn't.
Needed to be able to open the project by itself and build it, and deploy it independently from other projects. If built with project references, this sometimes caused issues with deployment, because a project reference caused it to look for a specific version or higher, or something like that. It limited the mix and match ability to swap in and out different versions of dependencies.
Also, I had projects pointing to different .NET Framework versions, and so a true project reference wasn't always happening anyways.
(FYI, everything I have done is for VB.NET, so not sure if any subtle difference in behavior for C#)
So, I:
I build against any project that is open in the solution, and those that aren't, from a global folder, like C:\GlobalAssemblies
My continuous integration server keeps this up to date on a network share, and I have a batch file to sync anything new to my local folder.
I have another local folder like C:\GlobalAssembliesDebug where each project has a post build step that copies its bin folder's contents to this debug folder, only when in DEBUG mode.
Each project has these two global folders added to their reference paths. (First the C:\GlobalAssembliesDebug, and then C:\GlobalAssemblies). I have to manually add this reference paths to the .vbproj files, because Visual Studio's UI addes them to the .vbprojuser file instead.
I have a pre-build step that, if in RELEASE mode, deletes the contents from C:\GlobalAssembliesDebug.
In any project that is the host project, if there are non dlls that I need to copy (text files outputted to other project's bin folders that I need), then I put a prebuild step on that project to copy them into the host project.
I have to manually specify the project dependencies in the solution properties, to get them to build in the correct order.
So, what this does is:
Allows me to use projects in any solution without messing around with project references.
Visual Studio still lets me step into dependency projects that are open in the solution.
In DEBUG mode, it builds against open loaded projects. So, first it looks to the C:\GlobalAssembliesDebug, then if not there, to C:\GlobalAssemblies
In RELEASE mode, since it deletes everything from C:\GlobalAssembliesDebug, it only looks to C:\GlobalAssemblies. The reason I want this is so that released builds aren't built against anything that was temporarily changed in my solution.
It is easy to load and unload projects without much effort.
Of course, it isn't perfect. The debugging experience is not as nice as a project reference. (Can't do things like "go to definition" and have it work right), and some other little quirky things.
Anyways, that's where I am on my attempt to make things work for the best for us.
We have one gigantic solution on the source control, on the main branch.
But, every developer/team working on the smaller part of the project, has its own branch which contains one solution with only few projects which are needed. In that way, that solution is small enough to be easily maintenaced, and do not influence on the other projects/dlls in the larger solution.
However, there is one condition for this: there shouldn't be too much interconnected projects within solution.
OK, having digested this information, and also answers to this question about project references, I'm currently working with this configuration, which seems to 'work for me':
One big solution, containing the application project and all the dependency assembly projects
I've kept all project references, with some extra tweaking of manual dependencies (right click on project) for some dynamically instantiated assemblies.
I've got three Solution folders (_Working, Synchronised and Xternal) - given that my source control isn't integrated with VS (sob), this allows me to quickly drag and drop projects between _Working and Synchronised so I don't lose track of changes. The XTernal folder is for assemblies that 'belong' to colleagues.
I've created myself a 'WorkingSetOnly' configuration (last option in Debug/Release drop-down), which allows me to limit the projects which are rebuilt on F5/F6.
As far as disk is concerned, I have all my projects folders in just one of a few folders (so just one level of categorisation above projects)
All projects build (dll, pdb & xml) to the same output folder, and have the same folder as a reference path. (And all references are set to Don't copy) - this leaves me the choice of dropping a project from my solution and easily switching to file reference (I've got a macro for that).
At the same level as my 'Projects' folder, I have a 'Solutions' folder, where I maintain individual solutions for some assemblies - together with Test code (for example) and documentation/design etc specific to the assembly.
This configuration seems to be working ok for me at the moment, but the big test will be trying to sell it to my colleagues, and seeing if it will fly as a team setup.
Currently unresolved drawbacks:
I still have a problem with the individual assembly solutions, as I don't always want to include all the dependent projects. This creates a conflict with the 'master' solution. I've worked around this with (again) a macro which converts broken project references to file references, and restores file references to project references if the project is added back.
There's unfortunately no way (that I've found so far) of linking Build Configuration to Solution Folders - it would be useful to be able to say 'build everything in this folder' - as it stands, I have to update this by hand (painful, and easy to forget). (You can right click on a Solution Folder to build, but that doesn't handle the F5 scenario)
There is a (minor) bug in the Solution folder implementation which means that when you re-open a solution, the projects are shown in the order they were added, and not in alphabetical order. (I've opened a bug with MS, apparently now corrected, but I guess for VS2010)
I had to uninstall the CodeRushXPress add-in, because it was choking on all that code, but this was before having modified the build config, so I'm going to give it another try.
Summary - things I didn't know before asking this question which have proved useful:
Use of solution folders to organise solutions without messing with disk
Creation of build configurations to exclude some projects
Being able to manually define dependencies between projects, even if they are using file references
This is my most popular question, so I hope this answer helps readers. I'm still very interested in further feedback from other users.

Resources