views:

148

answers:

3

I always run into a problem where my projects in Visual Studio (2008) become huge monstrosities and everything is generally thrown into a Web Application project. I know from checking out some open source stuff that they tend to have multiple projects within a solution, each with their own responsibilities.

Does anyone have any advice for how to refactor this out? What should be in a separate project vs. part of the web project? Can you point me to any reference materials on the subject, or is it just something you become accustomed to with time?

+3  A: 

Organize your project cleanly into namespaces. Namespaces should not be too big, not too small. Make each namespace have a public "interface" (i.e. a set of public classes) and don't access internal implementation details of the namespace from other namespaces. Different namespaces usually address different parts of an application, e.g. you'll have namespaces related to UI, business logic, helper functionality, etc. The Framework Design Guidelines have some good suggestions how to design namespaces.

When you feel that your project grows too large, simply identify sets of namespaces that are clearly related to each other and move them to separate projects. Since other namespaces already just use the public interface of the moved namespaces, refactoring the namespaces into new projects is merely a file-move-operation.

dtb
That makes sense. Do you try to keep class files in a project separate from the specific web project files? Or do you let them mingle (while namespaced). Are there any best practices for namespacing? Sorry, I know this is really basic, but I've been doing this for a few years now, and I've finally reached the breaking point of frustration.
Aaron
FDG book is the guide. Once you make out meaningful namespaces, try to levelize them and split the huge project into several smaller ones. I agree ReSharper is nice, but NDepend is even more useful. http://codebetter.com/blogs/patricksmacchia/archive/2008/09/23/getting-rid-of-spaghetti-code-in-the-real-world.aspx
Lex Li
+1  A: 

Start from the bottom up (your simplest classes that don't depend on anything else besides the Framework) and see if you can isolate the dependencies into functional units. For instance, if you have a bunch of data or business logic classes that reference each other, but never reference any of your UI classes, then you have a candidate for splitting off into another project. If you can't find clear separation points, then you have a design problem and should probably do some refactoring.

I also agree that using namespaces is a good place to start. Even within a project, you can often isolate or minimize dependencies in a way that naturally groups classes together. Putting them in the same folder reinforces this grouping as a functional unit and may really help the poor guy who has to maintain your code in the future. Trust me, I try to think about that poor guy because, on more than one occasion, that poor guy has been me. Twas a small comfort that the person who wrote the code had the same name as me at the time that he wrote it.

Dan Bryant
+1  A: 

Check out the guidance given by the Sharp Architecture project. Its ASP.Net MVC but the same principles apply to ASP.NET and other projects. The guys that put this stuff together are smart I generally use their advice as the default and only stray when I have a good reason.

The basic tiering that they propose is

  • A core project for your domain objects and interfaces for accessing external services (including persistence).
  • A data project that depends on core and implements all the interfaces for accessing persistence
  • An application services project for supporting application-level concerns such as logging or login validation. This only references core.
  • A web project that holds only views.
  • A controllers project that holds your bootstrapping code and the code for coordinating your web layer, domain.

In the case of an asp.net app I like to use the mvp pattern which would basically mean the

  • Web project holds your WebForms and codebehinds which should contain only the minimum amount of code required to redirect to the presenter. You probably also will need to put your bootstrapping code in there. This is due to an ASP.Net limitation and you should NOT reference any of that stuff from your codebehinds.
  • Controllers project is replaced by a presenters project. The big difference here is that somehow the presenter has to be instantiated by the WebForm rather than the other way around.

You can also try to check out the ASP.NET MVP project.

George Mauer