1.4 Organizing Your Projects
Several
different strategies are available when choosing a logical structure
for your projects and solutions. So far, we have just used a single
solution containing all of the projects that we are working on. (We
also saw how to make sure that the physical structure of the solution
on the filesystem matches the logical structure.) But there are other
options, and thinking about the structure of solution(s) and projects
before you start to write code will potentially save you time in the
end.Remember that a project may belong to more than one solution. This
gives us some flexibility in the way that we structure our projects.
We will now examine the three basic ways to organize your solution(s)
and projects and discuss their pros and cons.
1.4.1 Single Solution File
The easiest way to organize your projects is to put them all in a
single solutionthe approach we have used so far in this
chapter. The main advantage of this style is its simplicity. This
structure also makes automated builds simple, since only one solution
will have to be built. The disadvantage is the lack of flexibility in
a large projectany developers who wish to work on the solution
will always have to have all of the solution's
projects downloaded from the source control database.Problems can arise as the number of projects in the system grows.
Although VS.NET has no hard limit to the number of projects that can
be added to a solution, at some point a solution with a large number
of projects will become unwieldy. It can take a long time to open,
since VS.NET will check the status of every project in the source
control database. Large solutions will cause more memory to be
consumed. Big solutions may also present logistical problems if
multiple developers need to make changes to the solution files.
Another potential problem is that as the solution gets bigger, the
build time will tend to be unnecessarily high, as VS.NET may decide
to rebuild files that a developer may not even be working on right
now (although you can, of course, mitigate this by creating
configurations that build only subsets of the solution). The next
technique provides a solution to most of these problems.
1.4.2 Multiple Solution Files with a Master
The
multiple-solution-with-master strategy is similar to the
single-solution approach, in that there is still a single solution
file that contains all of the projects necessary to build your
system. The difference is that it is not the only solution file. This
master solution file will be used whenever the entire solution needs
to be built (e.g., for nightly or other automated builds). However,
the master solution will not normally be used by developers in their
day-to-day work. Instead, they will use other solutions that contain
only the projects they require to work on some particular aspect of
the system.To create one of these smaller solutions, you will start by creating
a new blank solution. But rather than adding new projects, you will
select Add
solution's context menu in the Solution Explorer.
(Or use File
Existing Project... from the main menu.) You can add as many of the
existing projects as you require.This method of organizing projects and solutions is likely to be
appropriate if you have a large number of projects (e.g., more than
10) and you want to make it easier for each developer to work on just
one portion of the software. Using a solution that contains only the
projects you need to work on has a number of advantages. It will
reduce the amount of time it takes to open the solution, especially
if the solution is in a revision control system. It will also reduce
the amount of unwanted information displayedthe Solution
Explorer, class view, and object browser will all be less cluttered
and therefore easier to use.
|
single-solution approach, you will need a little planning to take
advantage of it. You will not simply be able to pick arbitrary groups
of projects and create new solutions for themyou will be
restricted by the dependencies between the projects. For example, if
your solution contains a UI project that uses a class library
project, attempting to create a solution that contains only the UI
project will not be successfulit will need a reference to the
Class Library project in order to build. You should therefore try to
keep the relationships between your components as simple as
possible.[8][8] Issues with VS.NET project references
notwithstanding, it is good practice to minimize cross-component
dependencies in order to simplify your build and test procedures.
Large-Scale C++ Software Design (Addison-Wesley)
provides excellent and extensive explanations of why this is so.
Despite its title, many of the issues presented in this book are of
interest to developers creating large software systems in any
programming language.
there are multiple solutions, it will probably not be possible to
make your filesystem structure match all of the solutions. For
example, if we create solutions for working on a Windows Forms UI
project and a Web Forms UI project, both of these solutions might
need to contain the same Class Library project. Since a directory
cannot be contained by multiple parent directories,[9]
there is no single filesystem structure that matches both solutions.
The simplest way of dealing with this is to choose just one solution
and make the filesystem match that. The obvious solution to choose
for this is the master solution.[9] Strictly speaking, NTFS 5 reparse points do allow a directory
to have multiple parents. However, even if all of your
developers' machines have appropriate filesystems,
your source control system almost certainly won't be
able to deal with such a directory structure.
There will be some extra subdirectories in the master solution for
this approach. Visual Studio .NET insists on giving each solution its
own directory. (And although you can move .sln
files after VS.NET creates them, it will insist on putting each in
its own directory in your version control system, regardless of how
you may have restructured the files on your local filesystem.) So
there will be a directory for each secondary solution you create,
containing just the solution files. The project files will be inside
the project directories as before.Projects inside of the master solution can then be contained by
multiple different secondary solutions. This enables each developer
to download and work with only those projects that are related to the
part of the system she is currently working on. The only problems
with this technique are the constraints imposed by use of project
references and the fact that the master solution can become a
bottleneckanytime a new project is added, the master solution
will need to be updated. (In software shops where people are in the
habit of keeping files checked out for a long time, this can be a
problem.) The final way of structuring your projects can get around
both of these issues, although not without some inconvenience.
1.4.3 Multiple Solution Files with No Project References
If
you want developers to have the maximum possible flexibility as to
which projects they can download and work on, you could create one
solution per project and have no master solution at all. The cost of
this flexibility is that you have to deal with dependencies manually,
because VS.NET has no way of representing cross-solution
dependencies.It is likely that some of your projects will depend upon other
projects, but if they all live in their own solutions, you will have
no way of representing this formally. You will have to use .NET file
references instead of project references. This is inconvenient
because you need to delete and recreate the references (or delete the
copied component from the build directory) every time the component
you are using changes. It also makes automated builds harder, since
the build script will have to build multiple solutions, and it will
also be responsible for getting the build order correct.
|
1.4.4 Choosing an Organizational Method
The simplest
structure is the single-solution
approach. Using this will mean that your solution's
physical layout can easily match its logical structure, and you can
always use project references to make sure that every project will be
rebuilt and copied automatically when it needs to be. Choosing this
structure as a starting point is almost always the right decision.If the number of projects makes dealing with the solution too
unwieldy, then you should consider migrating to the
multiple-solution-with-master-solution structure. Your existing
single solution will become your master solution, and you can add new
solutions to partition your projects as required. When creating the
new solutions, you will find that if you include a project that has a
reference to another project, VS.NET will complain. (If you expand
the project's References node in the Solution
Explorer, you will see that the reference is still there but now has
an exclamation mark in a yellow triangle over it.) You will need to
add all referenced projects to the new solution in order to be able
to build it.If at all possible, you should always have a master solutionan
organization with multiple solutions but no master should be chosen
only as a last resort, as shown in Table 1-7. The
advantages of more flexible partitioning rarely outweigh the
disadvantages of not being able to use project references and the
increased difficulty of automating builds.