views:

439

answers:

4

Dear ladies and sirs.

We have a .NET project consisting of multiple subprojects (around 20). There are several solutions, each containing only those subprojects which are relevant to the particular solution.

To allow for arbitrary solutions, our subprojects never reference each other by means of project references, but rather by direct dll references. There is little tweaking of the csproj file, to make HintPath include $(Configuration), so Debug builds reference Debug dlls and Release builds reference Release dlls.

All works great, but there are two major problems - one is annoying and another is really acute:

  1. VS does not recognize dll references for the purpose of the dependency calculation. We have to manually specify the dependencies using the "Project Dependencies" dialog each time a new project or reference is added. This is annoying.
  2. We use neither Resharper nor Visual Assist (great tools, but we do not use them, it's a given). We do like to use the standard "Browse to Definition" command (available from the context menu on the source code, for instance). The acute problem is that it only works cross project if one project references the other using the project reference and it does not work when the reference is the direct dll reference, even if the referenced project is included in the solution! That's a real bummer, because instead of navigating to the source it navigates to the metadata.

I am seeking for an advice of those folks out there who use dll references like us and have somehow overcome these two issues. Thanks.

EDIT:

Note, that besides the "Browse to Definition" issue, having Dll references instead of project references incurs only one time cost on the project manager - which is to update the project dependencies of each affected solution when a new project is added or a new dependency must be introduced. These project dependencies are persisted in the .sln file and do not require any maintenance until a new project arrives or a new dependency is created, which happens not that too often.

We are using msbuild for building our projects on the CI server, which uses the same .sln files as VS does. There is one main .sln file, which includes all the subprojects.

I wish to emphasize the more acute problem - the inability to browse to a defintion in another project, although both projects are in the same solution just because the references are dll references. This is annoying and it is a nuisance, there is no reason why VS insists on project references to enable the feature. Other tools, like Resharper or Visual Assist do not have this limitation. Alas, we do not have these tools and unlikely to have in the observable future.

+2  A: 

Is there any reason why you want to allow for arbitrary solutions? It seems like it would be easier to create a single solution and put all of the projects in that solution. I try to avoid multiple solutions wherever possible.

Pedro
The more projects the higher the load time, plus it checks all the projects when building and if the major portion is unchanged it is too much of an overhead. A UI developer may never touch half of the projects, so why to pay the cost every build, plus the one time cost of loading the solution?
mark
A: 

Have you tried using ${ReferencePath} ?

Floetic
I have edited the question. Would you elaborate a bit your response?
mark
A: 

It sounds to me like the problems you are encountering are the direct result of using your tool set incorrectly. Visual Studio has no other way of automatically calculating project dependencies when you don't let it manager them.

It sounds like you have two choices.

  1. Use Visual Studio to manage project dependencies
  2. Use another build system (like NAnt)

It sounds like you have ruled out option #1, so I won't address that any more. So that only leaves option #2.

You could use NAnt to build your individual CSproj projects and use your NAnt build script to define the dependencies between projects. There are two downsides to this.

  1. You have to manage it all buy hand (which it sounds like you are prepared to do)
  2. Visual Studio would be equally as broken to you as it is now.

On downside #2, Visual Studio wouldn't be able to compile your solution as a whole because that logic would have been shifted out of VS and into an external build script. This could lead to confusion among developers, and would hinder the debugging process. Not saying those things aren't overcome-able... just saying that it would be extra setup involved at those steps of the development process.

Jason Whitehorn
I do not understand what Nant gives me as opposed to msbuild. Our projects are built with msbuild at the CI server and it works very well. The only problem, is that .sln files (which are used by msbuild as well as VS) must include project dependencies explicitly, because we reference Dlls rather than projects. That's all. I do not see why should I switch to NAnt.
mark
Thanks for the reply.I have edited my question.
mark
+3  A: 

The problem with your build configuration is the following: say you have 3 projects and 2 solutions.

Solution1
- Project1
- Project2
Solution2
- Project1
- Project3

All of a sudden, building Solution2 builds part of the code for Solution1, leaving it in an invalid state (the latest binaries are either incompatible or did not need to be built).

Every project should be included in a single solution. Other solutions can rely on, but should not actively change the code of those projects. In this way, they can reference a built DLL because there's no reason to rebuild the external dependencies.

To summarize, you should take some time and restructure your solutions to meet the following conditions:

  • Every project is included in exactly one solution.
  • If a project depends on another project within the same solution, make it a project reference.
  • If a project depends on another project in a different solution, make it a DLL reference.

In addition to the above, I recommend creating an "Externals" directory for placing builds in when they are referenced by other solutions. Say you restructure to the following:

Solution1
- Project1
- Project2 -> reference project Project1
Solution2
- Project3 -> reference Project1.dll

In this case, you'd place copies of Project1.dll and Project1.pdb in Externals\Project1\Debug and Externals\Project1\Release, and reference External\Project1\$(Configuration)\Project1.dll in Project3. Only update the builds in the Externals directory when you are ready to push the build to all your other solutions.

280Z28
Thanks for the reply.I have edited my question.
mark