Best Practices: Organizing Development Projects


Today I am sorting through some problems with a check in (not mine, but helping determine root cause). I now have things down to a single error:

image

So, I know my problem is some source file is missing from the drive, but not from the project. This means an errant check in, so I am on track. The problem is I cannot find the source in Visual Studio very easily because the project has been organized into folders and this particular project does not fit the organization scheme.

So, this led me to write this entry about organization of Visual Studio projects. I have a few rules I follow:

  1. Be consistent
  2. Have the file system match the project organization (optional)
  3. When you rename something in a file (class, project name), be sure to rename the files
    This includes class files, names of projects, etc.

You can live with just one of these, but doing both gives you a great leg up when it comes to maintenance. Now, I know we don’t generally think much about maintenance while we are building, but maintenance ultimately costs an business more time and money than spending a bit of time to make sure your file organized in a uniform and consistent manner.

NOTE: As an aside, I did find the test by searching for {COMPANY}.AppFramework.Services.Providers.ESTests. I found that the project was actually named {COMPANY}.AppFramework.Services.Providers.IntegrationTests. I will cover this in point #3. Below is the first line of the AssemblyInfo.cs file in the project {COMPANY}.AppFramework.Services.Providers.IntegrationTests:

[assembly: AssemblyTitle("{COMPANY}.AppFramework.Services.Providers.ESTests")]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

1. Be Consistent

This one is a bit difficult to give a concrete set of rules for, as the nature of consistency really depends on the way your organize your projects. When I am building a project, I tend to organize into buckets based on functionality. The most common buckets (which correspond to folders in my Visual Studio solution) are:

  • Core – The actual business logic that performs the behavior for the solution
  • Domain – Models and exceptions used across many/all projects in the solution
  • Experience – Projects to gain access to the functionality in the solution (User interface projects, service projects, etc.)
  • Framework – Common functionality
  • Persist – Functionality to persist state between sessions
  • Test – Tests for the various projects

But this type of organization can be less effective when you further break down a very large project, as I am working on now. So, to the problem at hand. I think I am looking for an Enterprise Settings test project, which is part of the service model for the project I am working on, but it is not found in the solution at the correct spot. In section #3, I cover this a bit more, as was already mentioned. Here is the Solution Explorer:

image

2. Have the file System Match the Solution Structure (optional)

This particular advice need not be applied if you keep the file structure flat, meaning all of the projects are folders underneath the solution folder (default behavior). As soon as you start to organize the solution physically, you have to make sure the structure in the solution explorer matches, however. If you don’t it makes files very hard to find.

Since I organize by “type” of project (Core, Domain, Experience, Framework, Persist, Test, etc.), I find it just as easy to create the projects in the proper location. Now, I am quite religious about this when I am creating projects for user’s groups and conferences, as it makes it easier for the person downloading the code to follow along. I am not as religious in the workplace, especially if there is no standard for organization in place. This is primarily to avoid restructuring.

Why avoid restructuring? There are a couple of reasons, but they primarily relate to Team Foundation Server and Team System. I imagine the same is true for any source control system, but reorgs in TFS are easier done when you rebuild a completely new project with the new organization. The problem there is you lose history. So, if you are using a source control system, you are back to leaving everything flat or having a firm, largely immutable, standard that is followed.

3. Be consistent in naming

This one is dear to heart, as I currently have to do a refactoring of class names, as some of the names we have right now are confusing or way to similar to other names.

What do I mean by “be consistent in naming”? If you are going to change the name of a class, you need to change the name of the file. It makes things much easier when searching for a file when there is a problem in Visual Studio.

As an slightly off topic subject, you should also not have multiple classes in a single file. I say “slightly” as multiple classes in a single file presents the same problem as having the file named one thing and the class named another.

I am a bit lax on project names, which was the core of the problem I was having today. BUT … and this is a big but … you need to make sure any disparity makes sense and a standard is written. For example, the project MyCompany.MyProject.SubArea.Influence.CoreTests.MSTest.Integration.dll can be shortened without much problem, as long as you follow the same scheme in all of the projects.

Summary

The main takeaways for this post are as follows:

  1. You have to take the time to refactor when you change things. This is not just refactoring of code to remove smells, but refactoring the project to ensure the naming is correct (to standard) and consistent (which the standard should cover).
  2. You need to consider both the structure on the physical drive and the structure in your solutions when you develop the standard to help with takeaway #1.

Peace and Grace,

Greg

Twitter: @gbworld

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: