views:

988

answers:

4

What directory/solution/project structure do you find to be the most manageable and convenient for medium to large projects written in C#? By "medium to large" I mean projects which include a diverse set of Visual Studio C# project types in a hierarchical structure with nested namespaces.1

I'm primarily interested in those project types found in the 'Windows' section in Visual Studio 2008: Windows Forms, WPF, Custom Controls for both and Class Libraries. Additionally, I'm using MSBuild (via Visual Studio) to build my project.

I've never found the default structure automatically generated by Visual Studio to be worth using. This structure has one folder solely for containing the solution and a nested folder for each project. I'm wondering if this is because of the scale of project I've used C# for in the past (small to medium). What benefits does this structure have for larger projects? Have you found it useful?

I'm also interested in things like folder names and their relation to namespaces.

The following are my personal goals for project structure.

Goals

  • Each project should be reasonably self-contained. That is, I'd prefer to be able to check each one out individually and compile it (where permitted by dependencies).
  • Navigating the structure should be easy.
  • Directory structures should map to namespaces in a clear and straightforward way.
  • Identifying solution files should be easy.
  • Projects should build with little or no extra effort in Visual Studio (MSBuild) at most or all levels of the heirarchy

    1. Please note that my use of the word 'projects' here means 'development efforts' except where explicitly noted.
A: 

Hi,

For C# projects, I use usually a N layer structure. Something like:

/projectname_interface_layer/ /projectname_service_layer/ /projectname_business_layer/ /projectname_data_layer/

This has the advantage of offering a clear logical separation between the different entities of the application.

Amokrane
+1  A: 

You may want to check out TreeSurgeon.

HTH, Kent

Kent Boogaart
+2  A: 

I currently use a structure where the whole system is split into logical parts, each part being a separate Visual Studio solution. Each such solution is contained in a folder structure looking like this:

[logical part name]
  |-doc
  |-lib
     |- // any non-GAC-assemblies needed by the projects in the solution
  |-src
     |-Production
     |  |-Project1
     |  |-Project2
     |-Tests
        |-UnittestProject1
        |-UnittestProject2
  |-tools
     |- // any tools needed for automated builds and such 
        // (NUnit, NCover, MSBuild tasks, ...)

This does require some moving around of files (output from one logical part that is referenced by another needs to be moved into that other part's lib folder, for instance) but this can easily be automated within an MSBuild script. We also have such an MSBuild script that calls the MSBuild scripts of each of the logical parts in order, and moves the output into the appropriate lib folders. This way I can build the logical part that I am currently working with in one step, and also make a build of the full system with one click (or, well, double click).

We have used that structure in the current project for the last year and a half or so, and it seems to work out rather well.

Fredrik Mörk
A: 

What we do:

We have separate solutions, subversion repositories, and builds for each layer.

Each layer has dependency builds so that building a lower layer will cause that layer to build.

Each layer has a Lib directory with externals pointing at the lower layer output directories.

Prior to a build, any layer(other than the root one), will do an update on the external folder(s), pulling the latest binaries in. If the build is successful, then it will update the external link to latest version, and then check in it's own binaries. This will trigger the next build down the chain, etc.

This way a breaking change in a lower level layer will fail builds up the chain, but if you do a get from the upper level layer it will still work in the most recent functional check-in.

As for deciding on layers, we pretty much have a framework layer, business logic layers, and presentation layers(either web service, application, or web site).

As for tests, they should be in the same solution as what they are testing, but different assemblies. The test assemblies should never be deployed to a production environment. The reason is that often, if not always, you will have your test assemblies be "friend" assemblies to the real ones. Assuming an attacker can execute any public members on deployed assemblies this gives them access to not only public members on your real code, but also internal ones.

Also, we keep things related to building, tools, config files, etc, in their own repository, separate from the code.

Darren Clark