Status
------
Currently we use two different methods to define references between
managed components, namely project references and .NET references to
reference assemblies (details below). Both methods are not fully
satisfactory. We would like to know:
(a) Is there is a better referencing mechanism available in VS8 (better
than the ones described below), or
(b) does MS plan to change the support for references in future versions
of VS.
Example Solution
----------------
ProjectA --> ProjectB
The source tree (after building) looks as follows:
Bin
ReleaseU
ProjectA.exe
ProjectB.dll
DebugU
ProjectA.exe
ProjectB.dll
Ref.Net
(ProjectB.dll) // only in method 1
ProjectA
ProjectA.csproj
ProjectB
ProjectB.csproj
There is a example solution added to this case
which is more than trivial, but is a good
playground.
Method 1: Reference Dlls
------------------------
A reference dll is a copy of the release version of the target assembly,
which is checked in like a source file.
The source project creates a .NET reference to the reference dll
via ProjectA/RightMouseClick/Add Reference/Browse(select b.dll)
In the above example, bin/ReleaseU/ProjectB.dll is checked into
Ref.Net/ProjectB.dll.
The principle is the same as that used for VB 6 "binary compatibility"
dlls.
The reference is stored in the project file as follows:
ProjectA.csproj:
<Reference Include="ProjectB">
<Name>ProjectB</Name>
<HintPath>..\Ref.Net\ProjectB.dll</HintPath>
<Private>False</Private>
</Reference>
Method 2: Project References
----------------------------
A project reference is stored in the project file of the source project
in the following format:
ProjectA.csproj:
<ProjectReference Include="..\ProjectB\ProjectB.csproj">
<Project>{17A348DA-0AFB-46C8-9FBA-9DAC268BE117}</Project>
<Name>ProjectB</Name>
</ProjectReference>
Using project refererences, the developer of ProjectA has to have
ProjectB in his solution, even if he does not develop ProjectB himself.
In the case of PUMA this means that the average solution of a UI project
has some 30-40 projects.
Pro/Cons of Reference Dlls
--------------------------
+ The developer of ProjectA does not need to include Projects B in his
solution, unless he wants to debug it.
- The developer of ProjectB has to update the reference dll when he
changes a visible (public or protected) member.
- The reference dll has to be locally available on the development
machine (can't use "T"-drive to build machine).
Pro/Cons of Project References
------------------------------
+ No additional reference dlls are necessary.
- The developer of ProjectA has to include ProjectB (and all components
that ProjectB depends on), even if he does not want to build or debug
them.
- When the developer of ProjectB add a reference (e.g., ProjectB ->
ProjectC) the solution for ProjectA fails to build.
- When the project GUID changes, solution files that include the project
have to be updated.
- The complete source of all projects that ProjectA depends on has to be
available on the developers machine.
In the ideal world...
To combine the advantages of project refs (no copying of dlls) and
project references (small solutions) we would like a reference
definition like the following:
ProjectA.csproj:
<Reference Include="ProjectB" </Reference>
To locate the actual dlls, we want to be able to specify a
configuration-specifc reference path on the project level, e.g.
<ReferencePath>
Release="..\Bin\ReleaseU; T:\bin\ReleaseU"
Debug="..\Bin\DebugU; T:\bin\ReleaseU"
</ReferencePath>
Close Solution with VS7
-----------------------
We had a near solution with VS7, but it was only near and seems
not to work with VS8 anymore:
With VS7 we found out that there is a folder in registry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.1\AssemblyFolders\<Product>
which's content is searched for assemblies need to satisfy
.net references
But with VS8
o) The above location is gone
o) It is not referenced during compilation
(We sniffed via Regmon during compilation)
o) If the above folder exists it does not address the
need of configuration specific dependencies
Big Picture
-----------
We have learned from out c++ past, that it is important
to give developers so called sandboxes, and this means
that they only have a part of the source tree locally,
work on it compile it, and the rest of the components
is somewhere on the net, and is referenced via a net
work drive. The network drive with all other components
is the overall source tree, which is the output of
daily build, so it is uptodate
This simple pattern can not be followed with the current
version of VS8, and I guess this will hit everyone
else, who does not small projects.
Kind Regards

What is the proposed way to define references in .NET?
MarcBey
> directory under my solution and any referenced
> assemblies go there. They may or may not be in CM
> depending on whether they come from an installed
> product or not. Finally note that referencing
> assemblies from a network drive should work. I don't
> know any reason why it wouldn't.
I personally also prefer the assembly reference pattern, because I need not to have everything in my solution, and solutions can be big.
The missing point for me is to specify more than one location for a already-but-not-by-me-built-assembly. I would like to give at least two locations for such an assembly. One one the network drive and one on my local drive. Because this would enable me to continue my sandbox pattern:
There is a nightly build, which compiles the whole source tree, even the base components, and shares the compiled source under a share. Fine. Everybody can access it.
Furthermore there is the 'sandbox' source of a developer on a local computer, which is only a subset of the whole source tree. So the developer does changes to components on his local source base, compiles, and to successfully compile needs a so called base-lib, because his components have a assembly reference to this base-lib. Unfortunatley she does not have the base-lib not on the local disk so the compilation would fail. If we now had a mechanism, which runs through the possible locations for a base-lib, it would find the needed assembly at least on the network drive ( because we sepcified so ) But it could also be found on the local drive, if the developer copied the base-lib manually from the somewhere to his own Assembly folder.
This is the thing we really miss, and I would love to see in 8.1, if you ask me for a solution proposal.
Maybe I can have comma seperated list in
<HintPath>..\Ref.Net\B.dll</HintPath> the .csproj, but it is cumbersome to manually add entries here. The IDE should support so called 'alternativ assembly reference locations'
( sounds not so bad ;-)
If you have questions to my proposal you can mail me at hermann dot schinagl at avl dot com
Kind regards Hermann
klva1
Anyone an idea how to solve this problem
Stefaan Smekens
AshClarke
Thanks for the info. I had read about "bin/$(Configuration)" part and it works fine. My concerns were about the assembly referencing that locks the file if Visual Studio is opened and about working with, for exemple, a GUI that references a business library and you need to work on both in the same day.
Do you use local assembly referencing or a network share The issue that I see with local assemblies is that another developer needs to get them as well, although this can somewhat be done with the source control. However, you need something to copy the file locally from your BIN to your "reference assembly" folder.
If you use a network share, you then have the issue that a build will fail if someone has his Visual Studio opened, and it also means it's not so easy to work with both the business component and the GUI that uses this library (for example).
As for the question about multiple solutions with the same project, yes the project has a reference to a solution, however, if you open solution (sln) files rather than the project files, there are no problems.
For example, I used to have 2 web sites (different security schemes, etc.) and a web services that uses the same business components; and because loading web sites was rather long in Visual Studio and that we never worked on more than one at any time, we separated that into 3 solutions with the same projects with the exception of the web site. It works as long as the relative path is the same all the way.
Maxime Bombardier
Hobbit666
(1) We use VS2005 with Team System source control.
(2) We always use assembly references, not project references (this is for scalablity). We can use our own non-source-controlled wrapper projects for local test development.
(3) We always reference the debug version of assemblies when adding the reference.
(4) Before checking in a project, we hand-edit the .csproj file, changing any "bin/debug" reference paths to "bin/$(Configuration)" (We have a tool that checks this has been done!)
Doing things this way seems to work fine. We can even go to the build configuration dropdown in the IDE and change from debug to release, and see the assembly reference paths change immediately!
usarcarib
Draggynsmate
Can anybody explain this:
I have a solution with two projects. Project1 builds a DLL, which Project2 uses. I am using Project reference option, because I am frequently debugging and recompiling both projects. So, in Project2 there is a reference to Project1. Why do I have to manually recreate that reference every time I switch between Release and Debug configurations in Project2 If I don't, VS will just copy Release version of Project1 into Debug folder of Project2 (or vice versa), even though in the properties of the reference the path is correct (release for release, debug for debug). Is this a bug or do I not know what I am doing
Thanks a lot,
Ilya
Marko Tekavc
Hi Hermann, there is a way for you to do this by modifying the <HintPath> in the project file. For example, In Notepad, open up your .csproj file and edit the following line(s):
<HintPath>..\<Path>\bin\debug\<AssemblyName>.dll</HintPath>
to say this instead:
<HintPath>..\<Path>\bin\$(Configuration)\<AssemblyName>.dll</HintPath>
This would make sure that the assembly corresponding to the active configuration is being picked up by the reference manager.
Hope this helps,
Prasadi de Silva
VS Core Program Manager
Yurgen
People at the office are all referencing assemblies located under a network folder. Some people are working in other locations (geographically), but connecting to the same source code repository. They reference the same assemblies (obviously... they are working on the same projects), but the assemblies are under local folders -instead of network folders.
The paths for the references seem to be checked in now in VS2005 That was different in VS2003 where the path for the referenced assemblies was not checked in, so everybody could have their own local path for them. This is a problem for us as we are working on the same projects and referencing the same assemblies, BUT in different paths.
Any idea for dealing with this
Thanks a lot!
Paul
hostile17
I've never been able to include a project in multiple solutions to be able to use project references. This is because I use the VS source control integration, and if that is used the project file include a reference to which solution it belongs. So adding the same project to another solution breaks the original solution.
Since noone in this thread has mentioned this problem I guess there is some simple solution to this problem that I've missed
Parv Sangha
Siddhartha Dutta
Thanks,
Murray
Email me here: murraybgordon at gmail dot com
cues7a
Anyway for completeness the results of
our investigations. Will add this as an enhancement
request.
> The setting you said was removed in VS 2005 I believe
> was moved to References tab in the project settings.
> Although I believe this only specifies what paths to
> search when using the Add Reference option. As far as
> finding the reference once it is added to the project
> it is irrelevant because when you add the reference VS
> stored the location of the original reference so it
> knows where to find it.
We have investigated a little more on the Reference tab in the
projectsettings, and found out, that you can add pathes
where the compiler searches for assemblies. Thats fine.
Not at all:
o) The content of the reference tab is not
configuration dependent, which means, that
we are once for sure referencing the assemblies
of the wrong configuration
Assume we have assembly reference path to
t:\assembly\release;t:\assembly\debug;
..\..\assembly\release;..\..\assembly\debug
where t:\ is a network drive, and ..\assembly
is the local sandbox drive. Then we compile
the release configuration of a component
with the need to resolve references.. fine
will work, because t:\assembly\release is
taken first.
If we compile the debug configuration of a component,
it will again resolve against t:\assembly\release
which is wrong.
So there is no way of correctly referencing
assemblies for both configuration with one
reference tab path setting
==> The content of the reference tab path' must
be configuration dependent.
o) The content of the reference path is not stored
in the x.csproj but in x.csproj.user which is not
a good idea, because the content of the reference path
tab *is* tightly connected to the project!
Jing Fan
I have a simple case where I have too many libraries and code to have a single solution; Intellisense simply eats my machine everytime I add a new line and make me wait a few minutes if I type '<' in Visual Basic.
Obviously, some of these libraries aren't modified daily so I can easily create a few different solutions. In that case, I have to switch to "Assembly Referencing", and Team Foundation's build server helps creating a shared area to get my references.
However, assembly referencing locks up the assembly while Visual Studio is still open. If a developer forget to close his solution / visual studio at the end of the day, the nightly build won't work. I could reference the daily folder, but that could be a pain as well, yet it gives me the ability to reference an older version if needed.
Any suggestion or guidelines on how to effectively use assembly referencing how about when we branch applications
Thanks,
Maxime Bombardier
Pavan kumar
Each type has its own usages. All-in-all project references are the best because they remove any maintenance work needed whenever the referenced assembly changes. You just see the changes. Unfortunately, as you mentioned, project references require that the project be included in your solution. This adds undo compilation (even if the source hasn't changed), increases the size of the solution and requires the source code. Project references are best used for projects that you'll have to build anyway.
Assembly references are used for third-party components and for projects that you don't build in your solution directly. This is commonly done for large products that would have hundreds of projects. There is no benefit in putting them all in a single solution if no one developer would ever be working on them all. Unfortunately assembly referencing requires that you keep the referenced assembly up-to-date with the builds. VS won't necessarily recompile your code just because a referenced binary changes.
For assembly referencing however you can store the assembly in one of three places: GAC, locally in the project or in an arbitrary location on disk. For signed assemblies you should retrieve them from the GAC. For third-party components you should store the assemblies in a dedicated directory under your solution so that all projects can reference the same binaries. I personally create an "Assemblies" directory under my solution and any referenced assemblies go there. They may or may not be in CM depending on whether they come from an installed product or not. Finally note that referencing assemblies from a network drive should work. I don't know any reason why it wouldn't.
Note that assembly referencing is actually a good thing because you can tell VS to target a specific version. This gives your app the side-by-side versioning support that it needs. If a third-party component you use ships a newer, buggy version you can just tell VS to use the previously unbuggy version instead. You can't do this with project references.
The setting you said was removed in VS 2005 I believe was moved to References tab in the project settings. Although I believe this only specifies what paths to search when using the Add Reference option. As far as finding the reference once it is added to the project it is irrelevant because when you add the reference VS stored the location of the original reference so it knows where to find it.
So, in a nutshell there are only 2 referencing options: project and assembly. Prefer project references when you are building the code already in your solution. It removes the requirement for validating dependencies. Use assembly referencing in all other cases and use either the GAC, the installation directory for commercial assemblies or a dedicated assembly directory for your own components. Don't forget to update the references and rebuild whenever the external assembly changes.
Hope this helps,
Michael Taylor - 10/11/05