What is the optimum number of projects in a Visual Studio 2008 solution? - visual-studio

What is the optimum number of projects in a Visual Studio 2008 solution?
We have one Visual Studio 2008 solution that is around 50 projects right now. It will likely continue to grow as the bulk of the projects within the solution consist of plugin assemblies for the main application.
If it seems like "too many projects" in one solution then how would you go about determining which projects should be grouped together in a solution? Given our example of approximately 50 projects in one solution with the bulk of the projects being plugins and with the number of plugins likely to grow, how should solutions be structured? Should all of the plugins be placed in their own solution? How should the organization change when the number of plugins in the plugins solution hits the magic number of "too many"?
We don't have any issues with this many projects in the solution ... it loads quickly, it builds quickly, it uses a reasonable amount of memory, and doesn't cause VS2008 to crash or bump up against any VS2008 bugs.
I've looked for documentation from Microsoft (there doesn't seem to be any) and Google searches yeild recommendations from "every project gets its own solution" to "place all projects in a single solution." Both extremes seem to be absurd. I'm looking for some reasonable guidance in the middle.
There have been other questions on Stackoverflow related to the maximum you've seen. That's not quite the same as what the optimum would be.

I'd say that you need at least 1 project for each layer on your system. If you need more projects, maybe it's a design problem. Meaning you can either "Over"-design or "Under"-design the application.
I nowdas use the following layers:
DataLayer - Responsible for the underlying data structure ( the database ). In the latest cases having the LINQ and partial classes for this in this project.
Interfaces - Having a layer for all interfaces, this to help extendabillity and not having to rely on some other layers to use these interfaces.
Logic - This defines itself, the business logic
GUI / Front - The Graphical user Interface ( Code )
These layers are the Minimum other Layers that COULD be possible would be Localization and other project that might grow.
But rahter simplify to directories and namespaces than using to many projects!

This is akin to discussions such as "how many functions should I have in a class?" and "should each enum be defined in its own .cs file?".
I would be interested to know how many classes each of your projects has. You can think of your classes, projects and solutions as organisational units. They are there to make your life easier, and to allow you (and your team) to break the overall project into managable conceptual chunks.
If VS2008 isn't complaining, and you and your developers have no problem with 50 projects in one solution then I would not worry about it.
That said, it does sound like a rather large number - but then we know nothing about the size of your overall codebase so it's hard to comment further.

Obviously when you get to 500 then you're starting to look at "too many" it becomes impractical even to manage it.
I might suggest that you analyse "what really constitutes my application" and package that as a single solution. Plugins are rarely considered part of the base application but add-ons to the base functionality.
If the application would cease to be useful without certain plugins, then include those in the base solution.
Other plugins might be grouped on Genre... much like the playlists on your iPod. What does each plugin achieve on a more general level? (These are obviously rhetorical questions) I would group plugins together in natural groups - much like PhotoShop plugins as they group on the menu. i.e. do they affect 3D, do they affect color, do they affect geometric effects, do they affect distortion etc etc.

When I see a slow down, I tend to create a solution that has references to built versions (assemblies) of dependent projects rather than the project files (for any projects that I don't need to see the source code). I only open the source for projects I am working on - surely nobody needs to work on the source of 50 projects at one time.
If you are already referencing the dependent assemblies rather than source, then I think it is just a matter or organizational preference (organize in a way that is easiest for you to understand and maintain).

Related

CQRS/Event sourcing project structure

I have my first CQRS project which uses event sourcing and I was wondering if this type of project should be structured in a different way in Visual studio compared to other projects that involve multiple tiers?
For example, in the pastt projects created had layers such as Remoting, App services, domain etc and it was clear each layer/assembly touched the one below it. These assemblies seemed to do a lot and using a tool like NDepend did say much about the structure of the project.
However, with a CQRS project would it be better just to have smaller assemblies that show their intent i.e. assembly for commands, another for events, another for event handlers etc.
Now with NDepend it would give me a better representation how the assemblies are used.
I generally structure my CQRS projects with smaller projects that are descriptive of their intent -- Command, Domain, Event, Denormalizer, Repository, Command Service, etc.
It makes it much easier to navigate through your solution this way, and also makes it easier for others on your team (or new team members coming on board) to work with the various components of your system.
Also, if you have a team working on this, you can easily let one group focus primarily on the domain project (probably your higher-end team members) while your junior members could work on the denormalizer project.
You'll end up with (probably) more projects, but they'll be smaller chunks and much easier to understand their purpose. Kind of like the Single Responsibility Principle, but at the project level.
Hope this helps. Good luck.

Looking for Suggestions on Microsoft Visual Studio Solution and Project Naming Conventions

There doesn't seem to be any tried and true set of best practices to guide you on how to setup your solutions, projects and the assemblies they output. Microsoft seemed to have tried back in the VS.net days, but they have since retired this content. For every method I read about I read another that claims the opposite is better, or a post that only concerns itself with "if only Microsoft would..." but really provide no solutions.
It appears there are many ways to do this that all seem to work for various groups in their situations, therefore I thought I would ask what conventions YOU use and why they work for YOU in your situation.
I hope that this will provide several good conventions for different situations, small development groups and projects to large diversely located development groups and projects.
What conventions do you use to...
name your solutions, and why?
name your projects, and why?
name your assemblies, and why?
know when to create a new project or add to an existing project, and why?
know when to split up a solution into smaller solutions, and why?
know when to break up a project into multiple projects, and why?
Just to be clear, the WHY is just as import as the HOW in these answers. There are many answers posted on the how here and other places, very few say why they use one convention over another.
That's a very broad question, but a good one. I will start with a simple structure that I use for ASP.Net web projects (MVC will look completely different).
Solution naming isn't a big deal to me. I tend to create solutions for a specific purpose, and add existing projects to the solutions. If your solution is over 15 projects (just a rough number) consider adding some of those projects as references. Most people don't need to work on more than 15 projects at a time.
Project Naming is a big deal to me.
// class library that supports the site itself and abstracts
// more complicated UI logic into a separate place
Company.ProductName.Web;
// website
Company.ProductName.Web.UI;
// main business object library for product
//
// of course, you can have as many of these as needed.
Company.ProductName;
I try to use enough folders in my projects so that all files in a folder can easily be viewed without scrolling the solution explorer.
My typical web project looks something like this. Note the different in casing to represent namespaced/compilable resources versus those that are not.
client (css, javascript)
config (private, custom config files, if any)
Content (Master Pages, ASPXs and ASCXs, broken into logical folders)
Handlers (ASHXs and such)
images
MSBuild (build scripts)
WebServices (these should ONLY be small services that are directly related to the site in question. Otherwise, break them into a separate project).
I've started using partial classes more and more to create comprehensive classes that can do many things without having the code be cluttered. For example, I recently created a web service whose single purpose is to return JSON to the client, but the logic is spread across almost a dozen partial classes to organize it better.
Hope that gets you started.
In our case we keep our project names quite identical to namespaces that we chose for particular assembly. That way it becomes easy to map location of a class file in physical folder. For example - CompanyName.BusinessLine.BusinessService or CompanyName.Framework.Security. So if a developer is looking at CompanyName.Framework.Security.Cryptography.cs, he can immediately figure out the project and open that project.
As Tim says, this is very broad. A few things to note:
A solution is usually just a collection of projects. Many solutions can include the same projects, for example. As such, it doesn't matter too much: if you don't like a solution name, you can throw it away with no refactoring at all.
Like Pradeep, I tend to name projects with the top level namespace they contain. "Deeper" namespaces end up in subdirectories, so classes within the Foo.Bar.Baz namespace might be in the Baz directory of project Foo.Bar.
I tend to split into projects across:
Elements of reusability (e.g. one assembly for a UI, one for a reusable set of model classes, one for a reusable general purpose utility classes)
Elements of deployment (e.g. one for production, one for testing, in pairs)
Elements of reference (e.g. if you have a common assembly Skeety.Common with some interfaces used by other classes, there might be a Skeety.Common.Testing assembly containing types which help you to test classes using Skeety.Common). This leads to these rules:
Production assemblies can only refer to other production assemblies
Testing assemblies can only refer to production assemblies and other production assemblies
Test assemblies (the ones containing the tests themselves) can only refer to production and testing assemblies, not to other test assemblies
No circular references are allowed, obviously
In many cases it actually doesn't matter too much how you split things up - but it does help to make the design cleaner as you work out the dependency layers (so a business logic assembly shouldn't have a reference to a UI assembly, but vice versa is fine).
Having too many project can definitely slow you down, both in terms of build times and just working out where everything should be. Having too few projects makes the design less clear. Over time you're likely to get more of a gut feeling for how things should be laid out - but I'm blowed if I'd claim to always know the best course of action :)

Visual studio solutions with large numbers of projects

I see developers frequently developing against a solution containing all the projects (27) in a system. This raises problems of build duration (5 minutes), performance of Visual Studio (such as intellisense latency), plus it doesn't force developer's to think about project dependencies (until they get a circular reference issue).
Is it a good idea to break down a solution like this into smaller solutions that are compilable and testable independent of the "mother" solution? Are there any potential pitfalls with this approach?
Let me restate your questions:
Is it a good idea to break down a solution like this into smaller solutions
The MSDN article you linked makes a quite clear statement:
Important Unless you have very good reasons to use a multi-solution model, you should avoid this and adopt either a single solution model, or in larger systems, a partitioned single solution model. These are simpler to work with and offer a number of significant advantages over the multi-solution model, which are discussed in the following sections.
Moreover, the article recommends that you always have a single "master" solution file in your build process.
Are there any potential pitfalls with this approach?
You will have to deal with the following issues (which actually can be quite hard to do, same source as the above quote):
The multi-solution model suffers from
the following disadvantages:
You are forced to use file references when you need to reference
an assembly generated by a project in
a separate solution. These (unlike
project references) do not
automatically set up build
dependencies. This means that you must
address the issue of solution build
order within the system build script.
While this can be managed, it adds
extra complexity to the build process.
You are also forced to reference a specific configuration build of a
DLL (for example, the Release or Debug
version). Project references
automatically manage this and
reference the currently active
configuration in Visual Studio .NET.
When you work with single solutions, you can get the latest code
(perhaps in other projects) developed
by other team members to perform local
integration testing. You can confirm
that nothing breaks before you check
your code back into VSS ready for the
next system build. In a multi-solution
system this is much harder to do,
because you can test your solution
against other solutions only by using
the results of the previous system
build.
Visual Studio 2010 Ultimate has several tools to help you better understand and manage dependencies in existing code:
Dependency graphs and Architecture Explorer
Sequence diagrams
Layer diagrams and validation
For more info, see Exploring Existing Code. The Visualization and Modeling Feature Pack provides dependency graph support for C++ and C code.
We have a solution of ~250 projects.
It is okay, after installing a patch for Visual Studio 2005 for dealing fast with extremely large solutions [TODO add link].
We also have smaller solutions for teams with selection of their favorite projects, but every project added has also to be added to the master solution, and many people prefer to work with it.
We reprogrammed F7 shortcut (build) to build the startup project rather than the whole solution. That's better.
Solution folders seem to address the problem of finding things well.
Dependencies are only added to top-level projects (EXEs and DLLs) because, when you have static libraries, if A is dependency of B and B is dependency of C, A might often not need to be dependency of C (in order to make things compile and run correctly) and this way, circullar dependencies are OK for compiler (although very bad for mental health).
I support having fewer libraries, even to the extent of having one library named "library". I see no significant advantage of optimizing process memory footprint by bringing "only what it needs", and the linker should do it anyway on object file level.
The only time I really see a need for multiple solutions is functional isolation. The required libs for a windows service may be different than for a web site. Each solution should be optimized to produce a single executable or web site, IMO. It enhances separation of concern and makes it easy to rebuild a functional piece of the application without building everything else along with it.
It certainly has its advantages and disadvantages anyway breaking a solution into multiple projects helps you find what you looking for easly i.e if you are looking for something about reporting you go to the reporting project. it also allows big teams to split the work in such a way that nobody do something to break someone else's code ...
This raises problems of build duration
you can avoid that by only building the projects that you modified and let the CI server do the entire build
Intellisense performance should be quite a bit better in VS2010 compared to VS2008. Also, why would you need to rebuild the whole solution all the time? That would only happen if you change something near the root of the dependency tree, otherwise you just build the project you're currently working on.
I've always found it helpful to have everything in one solution because I could navigate the whole code base easily.
Is it a good idea to break down a solution like this into smaller solutions that are compilable and testable independent of the "mother" solution? Are there any potential pitfalls with this approach?
Yes it is a good idea because:
You don't want VS to slow down on a solution with dozens of VS projects.
It can be interesting to only focus on a portion of the code, this enforce the notion of code locality which is a good thing.
But the important first thing to struggle for is to have as few VS projects/assemblies as possible. My company published two free two white books that explain the pro/cons of using assemblies/VS project/namespaces to partition a large code base.
Partitioning code base through .NET assemblies and Visual Studio projects (8 pages)
Defining .NET Components with Namespaces (7 pages)
The first white-book explains also that VS is pretty slow when working with a solution with dozens of projects, and shows tricks about how to remedy to this slowness.

Add all projects to same solution or not?

I am the intranet developer for the company I work for and I have been doing this for the last 5 years. My projects are divided into two solutions, the "Intranet" solution itself and the "Library" solution. The "Library" sln itself has several projects containing the DAL, BLL, etc.. The reason why I kept them in a different solution is because I thought that "maybe", one day my library sln can be used in other projects as well - you know reuse the code that I already wrote :) Well, that never happened. Now, since its so easier to have all projects in the same .sln, I am thinking to just do that. Is that a wise situation? What would you do if you were in my shoes?
In the past I've used and reused the same 'project' in multiple solutions - I really just see a solution as a 'particular' instance of a collection of projects.
For example, we might have different solutions for the same overall piece of software depending on whether we want to be doing unit testing (in their own project) and or integration testing (in a separate project), and we'd open the right solution for what it is we're about to do. That way if you're doing normal coding with unit testing you don't have to build the integration test code every time and visa-versa.
Only thing to watch out for is bringing in a project to a solution that is a dependency of lots of other projects/solutions and then "accidentally" changing the code in it without realising it's in a side project rather than your main code. Then you can start breaking loads of other projects that depend on it and not realise!
Yes, you can do it! You may still reuse your DAL and BLL, as the project settings are stored in the specific project files (csproj, vbproj, ...). Also dependencies are stored there, so no problem and good to go. I have an addin-infrastructure and for every and each addin-package, I do need the addin-host, which is included in several solution files. I never experienced any problems with this. Open up your *.sln file in a text-editor to see its contents...just links to the projects.
Simply add your library projects to your intranet sln. Keep your library solution as is.
I would personally all add them to the same solution, yes. Namely, it doesn't matter if you plan on using some of the libraries in the solution in other projects: you can still add the compiled dll to those solutions, or you have the option to add them as an exisiting project to the new solutions.
So yes, I add everything to the same solution: gui-projects, libraries, even unit tests. Maybe if your solution becomes incredibly large (20+ projects, or larger) it would be better to split them up, but I've never worked on such large projects.
I prefer to have 2 solutions. They both have identical structure (more or less) but the 2nd contains reusable infrastructure code only that isn't tied to a particular project. The thing is - your project code shouldn't contain framework-like (i.e. 'IsNumeric()' string extension method) stuff next to serious banking business logic (even if you won't reuse your 'Library'). That just makes things much more readable and maintainable.
For example:
Solution1:
ProjectName.Core
ProjectName.Infrastructure
ProjectName.Application
ProjectName.UI
ProjectName.IntegrationTests
ProjectName.UnitTests
And
Solution2:
CompanyName.Core
CompanyName.Infrastructure
CompanyName.Application
CompanyName.UI
CompanyName.Tests
And I try not to have more than 10 projects in 1 solution. Otherwise - it leads to infinite toggling between "unload project"/"reload project.
I, for my part, have separated the Solutions and the projects, leaving me with a big punch of projects and only a few solution-files. I add all the projects I need in new solutions.
The upside is that I only have the projects in my workspace which I really need and it still changes in all other solutions.
The downside is that it changes in all other solutions too, means that if you change the API of a widely used library, you'll have to check all your other solutions if incompatibilities.

Should a Visual Studio project be contained in more than one solution?

Note: This is for a shop that works in C++, C++/CLI, and C# with some products being delivered as a combination of all three.
We currently have a rule that a project should have one and only one containing solution. The rule was originally instated because the source control plug-in for Visual Studio was unable to cope with projects that were contained in multiple solutions, always attempting to change the source control bindings when changing from one solution to another.
For other reasons, we are going to stop using the source control plug-in altogether (not dropping source control, just the brain-dead plug-in). It re-opens the question of whether or not to continue the policy of restricting projects to be contained in only one solution.
We have quite a bit of code in libraries, dlls, and assemblies that are consumed by multiple deliverable products, and we currently control this with a system of inter-solution dependency management whereby if one is working in the solution for an end-product, it is a simple matter to request a build of the dependency solutions, which kicks off other instances of Visual Studio to build them. The system works, but has the following drawbacks:
The solutions for the common projects are often too fat, containing a few projects needed by the product being currently developed and usually a lot more that aren't needed for the development work at hand. They have merely been lumped into a sort-of catch-all solution that covers projects that are merely loosely related. This results in extended build times due to the compilation of unneeded code.
Where we have tried to address the above fat solutions, we are often left with a too skinny solution that contains just one project. Each of these requires additional configuration in the inter-solution dependency management system. This, too, can increase build times as multiple instances of Visual Studio are spun up.
I am considering revising the policy to allow a project used in multiple deliverable products to be contained in more than one solution. We could eliminate the inter-solution dependency management and severely reduce the number of solutions (down to one per product). I am concerned about the amount of work this reorganization will take and whether or not it will be worth the effort. I'm afraid I won't even be able to detect the potential benefits until the team has been working with it for a while. I also foresee a couple of potential issues which are the true questions here.
Do a large number of projects in a single solution pose any stability problems in Visual Studio 2005 (our current development platform)? Does it get any better in VS 2008 or VS 2010?
If a project is contained in more than one solution, how can one manage the effects on the multiple solutions should project configurations be modified (such as adding a new configuration)?
To anyone already working in an environment with one solution per deliverable product, with common components as projects contained in multiple solutions: Have you encountered any significant drawbacks to such a configuration?
No, use as many solutions as is convenient.
For example, we have a large solution that builds about 53 projects. It includes an installer and uninstaller so that they can be conveniently built by our build server, but if I want to work on those applications, I load them in their own solutions (1 project each), rather than wasitng all that time loading 69 other unnecessary projects. They don't have any dependencies on the other projects, so there's no problem at all doing it this way (indeed, it's a lot more efficient as the solution loads and builds way faster)
The only caveat of multiple solutions is that you have to be careful in any case where you don't build a dependency (e.g. if you don't build a library, then you need to be careful that it gets built whenever the source code for it changes, because it will no longer be built automatically for you)
edit
To answer the last part of your question (because SO takes the question away while you're editing the answer!), the only problem with Solutions in VS2005 is that it is very slow with a lot of projects in them. VS2008 is much faster at loading a large solution, but the main hit is just that the more projects there are in a solution, the longer it takes to build (even if it is just skipping projects that don't need to be built, it takes a long time)
If you add a new solution configuration, then just make one uber-solution (or just keep your existing one!) and then make your changes in that so that they are applied to all porjects in one go. You will still have to add that new configuration to any separate solutions you want to use, but if they're one-project solutions you can just delete them, load up the .csproj and it'll be rebuilt automatically with all the configs in it. And adding new configurations probably isn't going to happen very often.
The main problems with having one project in several solutions are:
If you make a change in the project, it may cause a compile error in another solution in which it is used.
The solutions must constantly be updated to keep up with the changes in the common projects
The benefit of having a project in each solution that it is used is:
It is easier to debug when you can follow the problem done to the souce code.
Another way to do it would be to have each solution use the the dll's of the common projects that they require. Then each solution can decide when they want to change which version they use.
The number of projects in a solution is not a major problem. But it will make the sollution slower to load and build. We have solutions of over 50 projects.
I too work in an environment that has many common projects that are used in several deliverables. Our policy has been one solution per deliverable application. So a common project may be included in several solutions. This has worked well for us. The common projects, while contained in separate solutions, all map to the same source code repository locations. So if the common code is changed, all containing applications are affected. Our continuous integration system serves as a check that other applications do not break as a result of the change to the common code.
The more projects you have in a VS solution, the longer it takes to load and it just sounds complicated having to manage different build configurations and dependencies in a single solution.
We have a "master solution" that contains over 100 projects. This took forever to load in VS.2005 until Microsoft released Intellisense fixes described here.
Our automated "continuous integration" build procedure always builds the master solution. For development, I divide the "master solution" into smaller solutions that contain a subset of related projects. Maintaining this structure takes some time when new projects are added, but is well worth it.
The only problem I've discovered with projects in multiple solutions is avoided by using $(ProjectDir) instead of $(SolutionDir) in build rules, as the latter depends on how the project is loaded.
Tools for SLN file (Visual Studio Solution file) contains a tool that:
Make it possible to create filters for a SLN file. The way it work is
that when the filter file is opened, a temporary solution is created
dynamically. The created solution file contain only the projects that
are specified in the filter, and all the dependencies of those
projects. This make it possible to have a mega-solution that contain
all the projects needed to build the complete system but still have
the possibility to work efficiently on a subset of the system.
This removes a big part of the cost of maintain sub-set solution files for speed of development.
However you need to ask youself if you have more project files then you need, as combining project files can speed up compiles and loading of soltuions greatly.
There is now a free Visual Studio extension, "Funnel", that solves this problem by loading predefined subsets of the solution. The link is for VS2012-VS2015; there is also a VS2010 version referenced on the extension home page.
You can set up multiple profiles (i.e. project combinations). These are stored in a parallel solution.sln.vsext file and that file can be committed and shared with your team. While VS2015 has gotten much better at handling large, 100+ C/C++/C# project solutions, I find it particularly useful for excluding makefile projects that are built every time the solution is built.

Resources