Managing and structuring software applications is a complicated topic. Many different ways of structuring applications exist, and there are merits to several methods of organization. In this post, I am going to roughly describe a method of organizing a software application to which I am somewhat partial.
One of the most important aspects of a well-organized project in my opinion, is the ability for a new developer on a project to be able to sit down and have a working solution as soon as they get the latest version of the application from the source control repository. Not only should that person be able to have a working solution, but that working copy should assist the developer in setting up the local environment. The solution should also be in a state which allows all of the project's tests to run without the user having to jump through a bunch of hoops.
Being able to sit down and start working immediately is very powerful. We wouldn't be able to achieve this without first having things packaged and tested nice. We are allowing anyone to figure out how things work based on the logic standardized and explained by our tests. The developer is now able to make meaningful, useful changes to the project right off the bat by making modifications and testing them. As long as they're not breaking existing tests, they can have some confidence that they're meaningfully contributing to the project.
Combined with continuous integration we are able to know that the project is in a tested, working state, and when we check out the source for the project, that it should work correctly already. There are a few pieces which must be in place in order for this to work. We need to make sure that the class libraries we're depending on are included in relative paths in the source control repository, so we don't have to worry about whether or not they are installed on the developer's machine. We also need to make sure that we have the project sufficiently well tested. Build scripts are also vital in allowing someone to sit down and start working immediately.
When deciding what tools to use for testing and for your build scripts, it is important to decide which tools you can safely assume will be on the developer's machine. As far as I know, you can't package MSTest or MSBuild along with your project. If everyone who uses this code will have these, then it is perfectly acceptable to depend on them. If that is not the case, I would recommend using NUnit and NAnt. These tools are very similar and are easy to use. Their integration with Visual Studio is not as nice, but they are easier to have dependencies on.
The trunk looks somewhat similar to this.
See that at this first level of the application, we have very little clutter. Things should be kept neat and tidy here, so that people just checking this code out aren't overwhelmed by anything before opening this. The lib folder contains class libraries that the project has dependencies on as well as the tools for building. This includes things like NUnit. By keeping it out here we are starting off having the opinion that these should be kept at arms length the whole time while working with the project. The less our dependencies integrate with our source the better off we are.
At this level inside the src folder, it is important to see that we still haven't shown any of our clutter. We of course get a lot more cluttered once we see the source code. I don't mean that the code is messy, but seeing a dozen files is a lot messier than a handful of folders and a solution. At this level someone can open up the solution and see the project from within Visual Studio already knowing that the solution works. How do we know it works? We ran the BuildAndTest file and it made sure that the project built and that all of the tests passed.
That little addition of having the ability to build and test the project is so valuable, because in a moment anyone can know if the project is working. We get quick feedback without even having to load visual studio. We don't have to search for the files among others; they're right there on their own.
Good luck, good organizing, good testing, good night.
And now an opportunity to promote Jeffrey Palermo's class. If you are interested in learning about Agile software practices, I recommend taking the Agile Bootcamp class offered by Headspring Systems. I learned a great deal from that class, and a lot of the practices I currently use are adaptations of what I learned. It isn't a class that tells you exactly how to do things, it shows you a way of doing things that works, which you will be able to take and adapt to how you're already working.