Considerations for large projects (Dynamic solutions)
The information is based on practices learned from my 4 year tenure as SW architect of a large (60 developers) team. I will show you how to get the most out of Visual Studio 2008 to help improve the effectiveness of your team-based software development using a tool that I am about to develop EasySolutionsA large project typically differs from a smaller project:
- You need to partition your project into multiple (100+) Visual Studio projects.
- You shouldn’t have to wait for several minutes before your IDE is responsive due to the fact that your solution is getting too big.
Building your projects for development
Something that I have learned is that you should never use solutions to build your project. Solutions are evil, really evil. You need them in order to work with Visual Studio, but that’s about it. You should never use them elsewhere and you should never commit solutions with the sources. Instead you should use MSBuild to build your project and you should dynamically generate the required solutions using a tool. Developing such a tool is no big deal. I will drop some bits explaining the idea and hopefully drop a first version of the tool in the next month or two.What you will get meanwhile is the outcome of some work I did waiting for my flight to Zurich returning from the p&p summit!
Building a Solution Generator
This idea is very appealing since the projects files are in xml and usually also in MSBuild format thus they are very simply to parse.The basic flow of such a tool is the following:
Search for project files (example *.csproj) recursively.
Load with XDocument each project and search for project references.
var projectReferences =
from element in xdoc.Descendants(xNameSpace + "ProjectReference")
select Path.GetFullPath(Path.Combine(projectDirName, (string) element.Attribute("Include")));
Create an object graph with all the project references per project and serialize it to xml for convenience. You will use this cache in order to avoid unnecessarily parsing the project files again. The schema of your xml is based on the following fragment…
[XmlRoot(ElementName = "Projects")] public class Projects : List{ } public class ProjectBase { [XmlAttribute] public Guid ProjectGuid { get; set; } } public class Project : ProjectBase { public Project() { } public List ProjectReferences { get; set; } }
You can now start querying that Projects instance typically using Linq. Generating a solution file is quite easy; the solution schema is very simple. {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") is the id of csprojects… Similarly you find id’s for all projects types supported.
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApplication1", "ConsoleApplication1\ConsoleApplication1.csproj", "{CD06FCD6-9F1A-4736-A034-925C24F628C3}"
EndProject
What you get from such tool:
- You are able to open only the necessary projects each time.
- You are able to make structural changes to your projects (add, rename, delete projects) without the fear that you will break other solutions.
- You don’t need to store the solution files in the source control.
Getting the tool one step further
Another point of pain is synchronizing all project properties across many studio projects (Some examples the output dirs should much, the build configurations should much, flags such generate doc and warnings should much and so on). The first problem is to find out the mistakes and there are tools around that will do this like BuildCop. The second problem is to go and manually alter all mistakes... fun job to do in a large project don't you agree? Well we could reuse the above idea, craft a simple gui to maintain project settings from all projects in one view and then directly save the changes into the visual studio project files. After all it's quite simple to alter XML...