Brendan Enrick's Blog

Daily Software Development.


Organizing Software Projects

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.

trunk-explorer

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.

src-explorer

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.

kick it on DotNetKicks.com

Trackbacks & Pingbacks

Organizing Software Projects — 12 Feb 2009 11:07 PM

Brendan Enrich has an interesting post on organizing the trunk of the source control for a system. Some of the principles include: Having all libraries with the source code Having a batch file for the build right at the top Sitting down and working immediately


Organizing Software Projects : Brendan Enrick's Blog — 12 Feb 2009 11:58 PM

Thank you for submitting this cool story - Trackback from DotNetShoutout


Reflective Perspective - Chris Alcock » The Morning Brew #286 — 13 Feb 2009 3:29 AM

Pingback from Reflective Perspective - Chris Alcock » The Morning Brew #286


Setting up the trunk of a project — 16 Feb 2009 4:03 AM

Pingback from Setting up the trunk of a project


Software Quality Digest - 2009-02-18 | No bug left behind — 18 Feb 2009 12:05 PM

Pingback from Software Quality Digest - 2009-02-18 | No bug left behind


Comments

 avatar

Jeffrey Palermo said on 12 Feb 2009 at 11:09 PM

What? No link to the Agile Boot Camp?

 avatar

Neil Mosafi said on 13 Feb 2009 at 6:52 AM

Couldn't agree more with your suggestions. Most projects use a database, so you'd need some scripts for creating the database - where would you put these?

I also think BuildAndDeployAndTest.bat is a useful thing to have. It would deploy and could then run some post deployment integration tests or UI automation tests.

 avatar

Jamie Ide said on 13 Feb 2009 at 7:56 AM

This is very similar to what we do and it's worked well for us. There are two aspects of this approach I've struggled with:

1. How can I keep the same version of dependencies in multiple projects? Take log4net and NUnit for example -- these are used in all our projects but we've been manually keeping the versions in sync.

2. What dependent files should I include? Everything in the dependent source code's /bin/Release folder? Or only the dlls that are referenced? Sometimes we end up with multiple copies of a dll in /lib if the dependencies reference the same dll.

benrick avatar

Brendan Enrick said on 13 Feb 2009 at 8:27 AM

As far as keeping versions the same, I believe the best strategy is to work with them manually. The reason for this is that it gives you the opportunity to make the adjustments the new version requires. If you automated the process you would potentially break the builds of different projects.

For a project I would recommend having one of each dll you reference in the lib folder. This way you have a nice easy location to adjust the assemblies of a project. Keeping them here with the project also allows them to be packaged nicely with the rest of the code.

benrick avatar

Brendan Enrick said on 13 Feb 2009 at 8:52 AM

@Jeffrey I was planning on adding one to the side, which I've now done. I've also added a comment at the end.

 avatar

Joshua Flanagan said on 13 Feb 2009 at 9:17 AM

I wouldn't discard MSBuild just because of concerns that you can't bundle it with your code. Its part of the .NET Framework - you dont NEED to bundle it. In your build.bat, just reference it using:

%systemroot%\Microsoft.Net\Framework\v3.5\MSBuild.exe

and it should safely work on anyone's machine.

benrick avatar

Brendan Enrick said on 13 Feb 2009 at 9:57 AM

@Joshua I don't discard it. I, in fact, still use MSBuild to build the projects I work on. I just prefer being able to deploy everything together, which is why I wish I could do this with MSBuild.

Thanks for the comment as well as the tip. It is definitely worth referencing MSBuild using the systemroot environment variable.

 avatar

Nick Gieschen said on 13 Feb 2009 at 12:47 PM

As a further level of organization I like making a tests folder in the src folder in which I place unit and integration test folders.

 avatar

Jeffrey Palermo said on 14 Feb 2009 at 11:41 AM

@Brendan,

Thanks, man :)

 avatar

Aleksey Maksimov said on 17 Feb 2009 at 4:44 AM

Though your project layout looks good, I prefer the Maven standard layout. It just looks more balanced and, as an additional benefit, allows you to have more than one language in a project.

maven.apache.org/.../introduction-to

 avatar

Pramatr said on 17 Feb 2009 at 7:46 AM

I couldn't agree more with the second paragraph. I've seen so many wasted hours on projects simply to get an evironment setup. In some companies, copying JARs from one people and pasting in some mystic properties files from another. Thankfully it's not like that here and our Wiki has a Team Project Set to pretty much set everything up for you.

benrick avatar

Brendan Enrick said on 17 Feb 2009 at 9:05 AM

@Aleksey Thanks. Yeah, the Maven layout is a nice one. It follows the same basic idea, and just organizes it a little differently.

@Pramatr Yeah, it is annoying having to do a bunch of that kind of stuff. I've seen some stuff where even after you get the project set up with crazy configurations, you have more configuring to do before the tests will run.

Comments are closed.