views:

77

answers:

3

There doesn't seem to be any tried and true set of best practices to guide you on how to setup your solutions, projects and the assemblies they output. Microsoft seemed to have tried back in the VS.net days, but they have since retired this content. For every method I read about I read another that claims the opposite is better, or a post that only concerns itself with "if only Microsoft would..." but really provide no solutions.

It appears there are many ways to do this that all seem to work for various groups in their situations, therefore I thought I would ask what conventions YOU use and why they work for YOU in your situation.

I hope that this will provide several good conventions for different situations, small development groups and projects to large diversely located development groups and projects.

What conventions do you use to...

  • name your solutions, and why?
  • name your projects, and why?
  • name your assemblies, and why?
  • know when to create a new project or add to an existing project, and why?
  • know when to split up a solution into smaller solutions, and why?
  • know when to break up a project into multiple projects, and why?

Just to be clear, the WHY is just as import as the HOW in these answers. There are many answers posted on the how here and other places, very few say why they use one convention over another.

+2  A: 

In our case we keep our project names quite identical to namespaces that we chose for particular assembly. That way it becomes easy to map location of a class file in physical folder. For example - CompanyName.BusinessLine.BusinessService or CompanyName.Framework.Security. So if a developer is looking at CompanyName.Framework.Security.Cryptography.cs, he can immediately figure out the project and open that project.

Pradeep
The Visual Studio "object browser" makes it simple to find the assembly containing a given class, regardless of namespace matches or mismatches.
Brent Arias
I don't recall if it tells you location of assembly as such the source code.
Pradeep
How would you scale this for a large enterprise application with dozens or hundreds of modules? How do you manage the projects and solutions if you have to refactor major touch areas that cross multiple projects and solutions? How do you manage company name changes since you have the name of the company in the namespace and project name?
Rodney Foley
+2  A: 

That's a very broad question, but a good one. I will start with a simple structure that I use for ASP.Net web projects (MVC will look completely different).

Solution naming isn't a big deal to me. I tend to create solutions for a specific purpose, and add existing projects to the solutions. If your solution is over 15 projects (just a rough number) consider adding some of those projects as references. Most people don't need to work on more than 15 projects at a time.

Project Naming is a big deal to me.

// class library that supports the site itself and abstracts
// more complicated UI logic into a separate place
Company.ProductName.Web;

// website
Company.ProductName.Web.UI;

// main business object library for product
//
// of course, you can have as many of these as needed.
Company.ProductName;

I try to use enough folders in my projects so that all files in a folder can easily be viewed without scrolling the solution explorer.

My typical web project looks something like this. Note the different in casing to represent namespaced/compilable resources versus those that are not.

  • client (css, javascript)
  • config (private, custom config files, if any)
  • Content (Master Pages, ASPXs and ASCXs, broken into logical folders)
  • Handlers (ASHXs and such)
  • images
  • MSBuild (build scripts)
  • WebServices (these should ONLY be small services that are directly related to the site in question. Otherwise, break them into a separate project).

I've started using partial classes more and more to create comprehensive classes that can do many things without having the code be cluttered. For example, I recently created a web service whose single purpose is to return JSON to the client, but the logic is spread across almost a dozen partial classes to organize it better.

Hope that gets you started.

Tim
How do you scale this to large enterprise class applications with tons of modules? How do you manage company name changes?
Rodney Foley
To start with, implement versioning and source control. If you change the name of the company, create a new version of the product and do a massive find/replace on the solution. Not glamorous, but it works, and with a versioned approach you don't break compatibility with products that depend on it. Regarding enterprise class, that's subjective...the biggest challenge will be keeping your UI application projects from spinning out of control. With the web, you can use a SOA in multiple projects; with Windows, forms/control inheritance can help split up massive UI projects.
Tim
Frankly, unless there was a huge business driver to do a rename, I would put that low on the priority list. Many companies (Microsoft included) will purchase a product and retain legacy names rather than dealing with the hassle.
Tim
How do you balance your approach with the packaging principles from Robert C. Martin (REP, CCP, CRP, ADP, SDP, and SAP)? These 6 principles are regurgitated my many over the last 14 years as how to manage your packages (aka assemblies, aka projects in .Net) however while they explain them they only provide simplistic examples and when to extrapolate these to large enterprise class applications it would seem that these principles end up making small packages of only a hand full of classes.
Rodney Foley
Link to all 6: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Rodney Foley
@Creepy - you've asked a boatload of questions there that are not quickly answered. I would suggest posting another question with a specific focus so that we can tackle that. In brief, A well-organized project structure can and should follow the principles you mentioned, but a lot of that comes down to skill and common sense on the part of the developer.
Tim
+1  A: 

As Tim says, this is very broad. A few things to note:

  • A solution is usually just a collection of projects. Many solutions can include the same projects, for example. As such, it doesn't matter too much: if you don't like a solution name, you can throw it away with no refactoring at all.
  • Like Pradeep, I tend to name projects with the top level namespace they contain. "Deeper" namespaces end up in subdirectories, so classes within the Foo.Bar.Baz namespace might be in the Baz directory of project Foo.Bar.

I tend to split into projects across:

  • Elements of reusability (e.g. one assembly for a UI, one for a reusable set of model classes, one for a reusable general purpose utility classes)
  • Elements of deployment (e.g. one for production, one for testing, in pairs)
  • Elements of reference (e.g. if you have a common assembly Skeety.Common with some interfaces used by other classes, there might be a Skeety.Common.Testing assembly containing types which help you to test classes using Skeety.Common). This leads to these rules:
    • Production assemblies can only refer to other production assemblies
    • Testing assemblies can only refer to production assemblies and other production assemblies
    • Test assemblies (the ones containing the tests themselves) can only refer to production and testing assemblies, not to other test assemblies
    • No circular references are allowed, obviously

In many cases it actually doesn't matter too much how you split things up - but it does help to make the design cleaner as you work out the dependency layers (so a business logic assembly shouldn't have a reference to a UI assembly, but vice versa is fine).

Having too many project can definitely slow you down, both in terms of build times and just working out where everything should be. Having too few projects makes the design less clear. Over time you're likely to get more of a gut feeling for how things should be laid out - but I'm blowed if I'd claim to always know the best course of action :)

Jon Skeet
How would you scale this? Lets say you have a large integrated business suite, and you make sure you follow DRY and SOLID principles. Lets say this suite has the following high level modules: CRM, ERP, PLM, SCM, SRM, etc. There is a lot of common code shared between them, and you also have a common user interface, and each one of these things has hooks/extension points where they integrate with each other. I can see how you can have solutions for each module, and these could be very big for these high level items.
Rodney Foley
@Creepy: The code shared between different solutions could either be in projects included in all of them, or just in class library binaries referenced by all of them.
Jon Skeet
@Jon Thanks, I seem to be having trouble finding a balance approach with the packaging principles from Robert C. Martin (REP, CCP, CRP, ADP, SDP, and SAP). Maybe I am just over thinking the problem, as it doesn't seem to be an easy task when I look at the current development project, while planning for the next development project, and attempting to take into account previous development projects. Maybe I should just stop, and only focus on the current, as it seems too difficult with the tools Microsoft provides with Visual Studio and TFS to really think any other way.
Rodney Foley
@Creepy - I think the better you get as an architect, the more you analyze each detail, and that's a good thing. When planning a project, determining the physical structure often leads a person to consider the big picture, whether it's reuse, abstraction, extensibility, etc.
Tim