Brendan Enrick

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.

Comments (17) -

  • 2/12/2009 11:07:47 PM | Reply

    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


  • 2/12/2009 11:09:03 PM | Reply

    What?  No link to the Agile Boot Camp?


  • 2/12/2009 11:58:10 PM | Reply

    Thank you for submitting this cool story - Trackback from DotNetShoutout


  • 2/13/2009 3:29:28 AM | Reply

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


  • 2/13/2009 6:52:40 AM | Reply

    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.


  • 2/13/2009 7:56:01 AM | Reply

    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.


  • Brendan Enrick

    2/13/2009 8:27:36 AM | Reply

    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.


  • Brendan Enrick

    2/13/2009 8:52:38 AM | Reply

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


  • 2/13/2009 9:17:20 AM | Reply

    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.


  • Brendan Enrick

    2/13/2009 9:57:26 AM | Reply

    @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.

  • 2/13/2009 12:47:45 PM | Reply

    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.


  • 2/14/2009 11:41:24 AM | Reply

    @Brendan,


    Thanks, man Smile


  • 2/16/2009 4:03:38 AM | Reply

    Pingback from Setting up the trunk of a project


  • 2/17/2009 4:44:05 AM | Reply

    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/.../...dard-directory-layout.html">maven.apache.org/.../introduction-to


  • 2/17/2009 7:46:21 AM | Reply

    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.


  • Brendan Enrick

    2/17/2009 9:05:30 AM | Reply

    @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.


  • 2/18/2009 12:05:10 PM | Reply

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


Loading