Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Structuring Solutions in Visual Studio and Team Foundation

Posted by Keith Elder | Posted in Uncategorized | Posted on 01-02-2007

Believe it or not, engineers or developers tend to structure their applications in Visual Studio various ways.  For those that are just learning .Net and Visual Studio it is hard to decide where to put things.  Hopefully this article will provide some guidance.

Where did I put that file?

So you’ve decided that you want to write an application in .Net.  For learning purposes you start adding controls or pages to your application and you are well on your way to making a somewhat usable app.  After awhile you start to notice your solution becomes a cluttered mess with files and folders and it becomes hard to remember where you put things.   This can be considered both good and bad.  You get complete flexibility in one hand and utter chaos in another.  Those that are used to other frameworks like Rails or LogiCreate understand you put this here, that here, that there, and this over there named this way or things don’t work.  In .Net it is so flexible when starting a project it is hard to get a good sense of where you *should* put things. 

If you downloaded 10 projects from http://www.codeplex.com or http://www.sf.net you’ll find 10 different ways of how things are organized.  Flexibility is great, but when you are trying to organize your development teams to develop applications so team members can move from project to another this isn’t good.  Consistency is the key to productivity.  There is guidance on how to structure solutions and projects from the Patterns and Practice team but it is dated I think and doesn’t go the extra deep dive to explain really where / how to structure things.  Here are some base line tips to get you thinking about how to organize your projects.

Tip #1:  Change Default Options

When you first install Visual Studio, the first thing I do is turn on the feature to always show the solution.   I’m not really sure of the reasoning why this is even turned off but you’ll find this settings in the Tools menu:

When this is enabled you’ll be able to easily access menus for adding your solution to source control, configuring certain projects to build or not build depending on your needs and another option that is very useful which is Clean Solution.   With the solution shown in the projects window here is a snap of that menu when you right click:

Tip #2:  Solutions are Deployable Entities

I can’t really stress this enough but to me it is just common sense, yet I see solutions all the time that are made up of multiple projects which are deployed separately.  I never mix solutions which have separate deployable projects.  For example, if I am building a Smart Client application, the web services used for the Smart Client application will reside in another solution.  They may, and can share some of the same common libraries but it doesn’t matter.  If I want to work on a web service because I’m changing the business rules or adding a new method, I don’t want to look at everything else, just the items I need.

When you leverage the build feature in Team System, this starts to make more sense since you specify a solution to build.  Combine automated builds with automatic push utilities and you start to see where I am headed.  The other reason I think of solutions as deployable entities is because different teams or team members may work on various portions.  Having separation is good because various teams can work on separate modules and backend services and not have to worry with conflicting solution files in Team System which are hard to resolve. 

Tip #3:  Folder Structure

This tip is probably the most talked about topic when I speak at various events.  Everyone is curious about where or how to name certain things.  This is also something I devoted a large amount of time to several years ago to figure out what works and doesn’t work.  I understand that what I suggest may not work for every scenario out there, but it does work and has proven itself to be very easy to manage.  Even for developers moving from project to project to understand.

Here is a screen shot of a slide that I recently added to one of my presentations which shows how I structure applications on the file system.

On the file system we have a folder called “EnterpriseDesktop”.  This is our folder where the source files will be checked out from Team System.  This could be c:\development\EnterpriseDesktop or d:\teamsystem\EnterpriseDesktop depending on where you want to put things.  Under this folder we have all the files that belong to our project.  The first thing you should notice is everything resides under a folder called “Source”.  This is intentional because it allows us take advantage of a feature in Team System easily called “Branching”. 

Since our entire application resides in the Source folder, we can easily branch this folder into a future release with new features, ongoing bugs, or multiple branches which would allow us to then merge it back into the main trunk later on.   For more information on branching in Team Foundation see this article on Branching and Merging Team Foundation Source Control.

Modules
Underneath the Source folder we see a module called Help Desk outlined.  In larger applications, it is easy to break down the application into modules.  No matter if your application is a web application, you can still think in terms of modules.  Very simply, just think of your features and break down your features into different modules.  In some cases you may find this doesn’t work and that is fine. Normally on smaller applications it doesn’t make sense, but if you are building larger ones, it does.  Even if you have a smaller application you still can choose to build out an N-Tier architecture with your project in which case this theory still applies.

Tip #4:  Modules Are Made Up Of Projects

Modules are simply a collection of sub projects.  If we look at just a module as outlined below we see the module is made up of several layers:

  • UI
  • Data access
  • Business
  • Workflow
  • etc…

For each layer we create a folder on the file system.  In this folder we create our project.  Each project folder is green above.  Taking this approach aligns our projects according to the namespace we desire since the namespace is derived from the folder hierarchy.  Taking this approach means you don’t have to remember to change the namespace setting manually in Visual Studio and since the folder structure inherits or outlines our desired namespace it is easy to understand.

For example let’s say I have a Windows application called EnterpriseDesktop and I want to add a Business layer which holds my business rules.  Simply by the way I create the project determines the Namespace of this and the location.

Why did I call the name of the new project I was adding “EnterpriseDesktop.HelpDesk.BusinessLayer”?  The reason is because if you look at the folder structure outlined, that is essentially my folder structure and my Namespace.  The Name field translates into a Folder.  After pressing the OK button your folder structure will look like this:

This makes it incredibly easy for developers to understand where files are located, what the Namespaces are etc.  For those that revel in Namespaces, it becomes apparent where / how you place things.  If you decide to create a namespace like System.Data.SqlClient it becomes apparent where those files are located in the hierarchy if you want to reference just the project for a given namespace.

Question?  Why the redundancy in folder names?  Wouldn’t I just put the project in the EnterpriseDesktop->Source->HelpDesk->BusinessLayer folder?

Answer:  No!  The reason is this.  What if you decide later on to sub-namespace the business layer or any other one for that matter?  You have no place to go then with the pattern.  By keeping things separate we don’t run into this problem.

Tip #5:  Where do the solution files go?

Since you need to branch the entire source control, the solutions need to go in the root of the Source folder.  It is ok to have several solutions if you have different deployable entities.  Remember, solutions are for deployable entities.  In the case of a web application this might be a console application, windows service, web service or a backend web solution.  I typically use this standard for solution files:

ProjectName.DeployableName.Master.sln

In the case of EnterpriseDesktop where we have a user interface and a help desk module, I would have the following solutions in the Source’s root folder:

  • EnterpriseDesktop.WinForm.Master.sln
  • EnterpriseDesktop.HelpDesk.WebService.Master.sln

Tip #6:  Where do I put Third Party Assemblies?

Most applications you build are going to leverage third party assemblies.  Either those you download for free or those you may purchase.  In the root folder of your source tree, create a folder called ThirdPartyAssemblies.  In this folder, nest each of the third party utilities your application leverages. 

While this may sound like common sense, I’ve seen projects in Team System or other source control systems which leverage ThirdPartyAssemblies from totally different projects, or even worse, require the developer to install a certain package onto their machine like Enterprise Library.  When you checkout your application from source control, you should be able to build right then and there.  No additional downloads, installs, or updates from other projects.

If you don’t include your own version of your own assemblies in your source control tree you are looking for trouble.  It also complicates ease of use, as well as complicates automating builds.  I’ve even seen situations where a developer referenced a third party DLL from another project that was in a totally different source tree and didn’t know why their application broke all of a sudden.  The reason was that a newer version of a DLL was replaced that broke their app.   Here is a screen shot to outline how I structure this on the file system. 

Question?  Will this work from machine to machine?
Answer:  Yes!  The reason is when you add a reference to an assembly in ThirdPartyAssemblies, the solution doesn’t hard code the path, but rather uses a relative path like this:  ../../../../ThirdPartyAssemblies/EnterpriseLibrary/RunTime/Microsoft.XXX.XXXX.DLL.  This ensures everyone gets the same version of each assembly no matter if they use a C: or a D: or where they place the source code on the file system.

Conclusion

There you have it, the howto guide on setting up your application with Team System and Visual Studio.   I understand that not everyone does the same thing the same way, but there is a lot to be gained if we all agreed on a standard.  Obviously other projects have agreed and look at what it has done for them.  Case in point would be Ruby on Rails. 

In the .Net space we do have something on the horizon which may assist us in getting closer to a standard similar to Ruby on Rails but right now it is too early to tell.  What I am referring to is the “Guidance Automation Toolkit“.   Several Software Factories are currently using this to guide developers on where to place things but it would be nice to see this expanded and become a major feature.  The idea behind the toolkit is architects or other developers could create guidance packages which force developers to code in their standard.  In other words, if I told Visual Studio that I wanted to create an Enterprise Web Application or Smart Client, decisions would already be made on where UserControls, Forms, Web Services, Documentation and more have to reside in order for my application to function.  Today, we see a glimpse of this when using the Smart Client Software Factory or the Web Service Software Factory.  I would like to see it expanded though, there is a lot to gain from having standards, not just in code, but structure.

Like this article? kick it on DotNetKicks.com

Technorati tags: , ,

Comments (24)

If you used a nuget package then they are not referenced from that location. 

Build an assembly of it and drop it into your lib or third party folder, if you include the debug files and everyone has it in that same location then you can debug into the files. Another option is setting up a source server.

 Thanks for the prompt reply.  I noticed a “packages” folder in my MVC 4 solution (created using the VS app type option).  But, interestingly, the app DLL references are not referencing that location – it appears by default they reference copies in c:program files (x86)Microsoft ASP.NET…  I guess I need to remove those default references and add the references from the location under the project structure (something other than “packages”, preferably).  Let me know if this is not the best approach.

Finally, I have common library code (separate “team project”) that will need to be shared with my project.  I’d like to have access to the source project from the solution in case I want to easily make tweaks and improvements (and debug) as I go.  But under these standard schemes that code would need to be included under each project tree.  That would seem to violate a rule of having code in one place.  What is the recommendation for such a situation?

Should be in a folder called lib or ThirdPartyAssemblies. Whatever you want to call them. If you look at how Nuget works my recommendation is no different. When you pull something down using Nuget it puts it into another folder called packages. Same thing.

Not necessary.

Another question: if we use the MS MVC framework, does that prescribe copying those assemblies to the team project’s ThirdPartyAssemblies folder and referencing those copies in the projects (rather than referencing from the default install location)? I assume yes.
Thanks.

Thanks, K. I’m new to TFS and this helps. The MS P&P shows a similar structure, though they include a “Main” folder above “Source”, as well as another “Source” folder to contain projects under an app; e.g., under your HelpDesk folder. Do you think that is not really necessary?

I assume all of this pertains to TFS 2010 as well, correct?

Great post Keith!

I’m in the process of migrating from SourceSafe to TFS and still not sure about how to structure things…

My problems are “only” with COMMON FILES. We have lots of common code that we use in different projects. Now, under SourceSafe we have that common code “shared” which is not available under TFS. I understand “sharing” breaks branching/merging model but still not sure about how to deal with that!

One solution can be to branch/merge that common code. This solution seems to be hard(time) to maintain… and not easy to determine merge candidates until new branching/merging visualizations come with TFS2010…

Another solution can be to place that common code in the same level as the other projects and reference it relatively from each project. But in that case, the branches will not cover that common code!

Other solution can be to treat it as thirdparty but still don’t like it very much… What do you do with third parties placed in several projects? Do you manually update each project when a third party changes?

What do you think?

Thanks,
Sergio

@Amitn

I don’t combine the subclasses of tests in the same place as the main projects. I do it like this:

Tests/UI.Web.Tests

And include all of the tests there for all things I need to tests.

As far as running out of character you certainly can but you can shorten the folder names because there is no sense of repeating.

Example:

UI/Web/Deploy/UI.Web.Deploy

could just be:

UI/Web/Deploy/

The main take away from this is that you seperate and break down the projects by namespace so each one lives in its own folder.

-Keith

So say I have UI/Web/UI.Web like you said.
Now I want a deployment project and a unittest project. So does it become:

UI/Web/UI.Web
UI/Web/UI.UnitTest
UI/Web/UI.Deploy

Or, I think by your pattern that allows growth:

UI/Web/UI.Web
UI/Web/Test/UI.Web.UnitTest
UI/Web/Deploy/UI.Web.Deploy

?right?
And then it gets even more complicated if I need to add tests to the deployment project…I may run our of characters…
Sigh. This is tough.

@Ian

I agree and there really is no reason repeating the folder names.

I typically name them on the latter part of the namespace. Like, the example above, I would call the folder UI.Mobile for example. We already know which namespace we are in based on where we put it, no need to repeat all of that.

Before sticking in the full namespace in the folders that TFS uses make sure you realise that TFS build agent doesn’t supports more than 260 characters in the path.

social.msdn.microsoft.com/…/919c0c17-c08f-46a…

until this gets increased I suggest not using the full namespace to name the TFS folders on large projects.

How would you handle structuring sub-websites (seperate applications)? I would like to merge new applications into a new directory trees on a website.

Hey Tim,

Looking at what you have in your folder structure everything without an asterisk is just part of the solution. There is no way to get rid of that stuff as it is still needed in order to make everything else work. Honestly, it has never bothered me. I look at it as it is what it is and I move on.

The items you have with *’s you control the structure of those and the things I showed above do come into play they just may not be as “obvious”.

As an example, each of the items you have (with the exception of documentation which I don’t think should be kept in a project, personal preference) can be placed in a SEPARATE project.

Look at the screen shot above where I have a module. See the green project folders? Well, replace the DataLayer one with “Dao” as you called it. And add a new one to that called “Core” and another one called “Util”. Each of those are technically namespaces in your application and it is better to separate those concerns out into other DLLs (or projects) in most cases.

The whole purpose of this blog article is to get developers thinking about organization because it matters. Take a look at the power point presentation I do on organization. You can find it here, it may further help.

http://keithelder.net/Presentations/VisualStudioStructureAndGuidance/StructureAndGuidanceForVisualStudio.pptx

Thanks muchly for taking the time out on this. I’m new to .net (having done java for years) and was struggling a bit on the best project structure (still am to be honest).

You’re structure makes sense but… do you have any suggestions for how to deal with such things as test resources, config files etc. The way I see it many of these files/folders would still end up alongside source folders (as they often relate to the module rather then the solution). For example, one small project I have already has the following folders/files at the top level (those marked with * are source folders)…

References, Properties, Core*, DatabaseScripts, Dao*, Docs, Resources, Util*, app.config

And I don’t see how that would change with the structure above.

Maybe it’s just me but I hate how the non-source folders/files infect my lovely source folders:( Simpler code browsing aside, it’s so cathartic seeing a clean set of folders clearly demonstrating the way you’ve broken down the components of your module

I don’t have a screen cast of this yet but I am planning on putting one together.

Great posts! Quick question…I was initially attracted to your page because of the reference to modules in my google search.

But, the modules were not what I thought they would be…do you know if its possible and if so how to set up groups of projects? What I mean by this is we have two divisions…each with separate projects…can we set up two master projects that these sub projects (each with work item tracking, bugs, etc.) present?

Then just shorten the folder paths. Instead of full name spaces use something else. The main thing that I think you should follow is a standard. I have a very large system that this works for fairly well but I will say that if I have my project in a folder starting like c:\development\MyCompany Name\Team Foundation Server\Project Name

Then yeah, the base path is already too long. Just shorten it to: c:\Project or c:\Dev\Project

Also question youreself on how you are breaking things up. If there is that many levels of sub folders is that a good design. I’m not saying it isn’t but something with that many folders may need to be looked at. Either way should work. Thanks.
-Keith

Thank you, but I have this problem

I couldn’t apply your method, but when I try I get message from visual studio saying the path is too long. Try to add more inner (sub projects) projects to the folder Development\EnterpriseDesktop\Source\HelpDisk\BusinessLayer\

You will get the same error. What to do with this.

My project is too big and have many subfolder projects

@Ricardo

There are technically two types of solutions as I like to call it:

1. Deployable solution whereby what is in the solution is what is going to get deployed.
2. Master Solution – this is a solution which is made up of every project in your application.

The “Master Solution” serves one purpose and that is for continuous integration (unit testing). When you are dealing with larger projects where you have a winform solution, several web services deployed, maybe a couple of windows services, some console apps that run automated updates and purging at night, and so on, you really need to test your entire application across all boundaries. The master solution serves this purpose since everything needs to build and be tested as a single entity. Any one part of it fails, then the system is technically broke.

In this example of a Master solution it is acceptable to have a service and other things in the same solution. However, you are still going to deploy them seperately so you’ll have three solutions in this case:

1. For the client
2. For the middle tier services
3. Master solution containing everything

I have never, ever never ever had something that was auto generated for me in Visual Studio when it came to projects that set things up the way I wanted. The only thing that comes close is the Guidance Software Packages like WSSF whereby it will create things as I outlined above, well almost.

Even with the guidance package, once it generates the stubs of the projects for me, I remove the projects from the solution, and organize them as I have laid out above. It takes only a few minutes to remove the projects, move the folders around and get things setup so it makes sense. They are really close to how I setup my stuff but I think mine makes more sense and is easier to teach and understand.

Hope that helps.

Re: “solutions are deployable” – When I make a new project in Team System and use the Distributed System diagram to make a system with a smart client using a web service, the auto-Implementation of that diagram places both the client and web service in the same solution. Yet you talked about VSTS Build and how it seems to fit well with the “solutions are deployable” model. Can you talk about these two seemingly opposing models?

Very good guidance post. My team was scratching it’s head over many of the points you mentioned. One issue we debated a lot was tip #4, Modules Are Made Up Of Projects. We are developing under the CAB. We are comparing the folder structures you recommend to the folder structure in the CAB bank Teller application (Hand-On Lab) and the folder structure generated by the SCSF and found many differences. Our primary concern was exposing the proper namespacing in a MVC pattern the CAB implements. (i.e. defining the proper subprojects to create.)

We settled on placing the UI elements you broke out into the BusinessLayer since workitems spawn thier controllers. And creating a project for the business layer and the datalayer within the module.

Does this sound right? Or would you recommend a different strucutre?

This is a tough question to answer because the way your question was asked is in a way that you think the way you are currently doing things is wrong. I don’t think it is wrong. Keep everything in one solution is my short answer.

For me, the simple answer is to put everything into one solution and then reference those plugin projects. I don’t see why you would not want to develop in this way. Meaning put a break point on a plugin, and press F5. You are in fact building the plugins against the host application which is the right thing to do I think.

The other thing you could do which is going to cause you a maintenance nightmare is to treat them as ThirdPartyAssemblished as I outlined in Tip #6. This is a MUCH MUCH MUCH harder way to deal with if those plugins changed constantly. I only do this on things that are truly third party which means they don’t change at all hardly, or I don’t want to branch the source from a common library.

If you are using TFS, the answer may simply be to setup alerts so the team knows when something else is changed. This would seem to solve your problem. You really don’t have a structure problem you have a how to use source control problem. People that have worked with source control systems for a long time understand to always get latest, and to do that alot. Anything that was chekced in, should have unit tests, and by george work. NO exceptions.

So. I say keep it in one, setup alerts, and train everyone to update source control. That is a lot simplier than creating yourself 5 hours of extra work a week just because people can’t remember to update source control. Once they break things several times they tend not to forget it again. 🙂

Very interesting and useful post…
I’m in process of restructuring an horribly structured development tree.
Here the task is made difficult by the fact that here we are building an "host" winform application that will load at runtime some other "plugin". So no strong references available, so what developer did here was putting everything inside one big solution, so that they can run debug the host application project while debugging the single plugins. But drives a lot of changes in the host just to fit one plugin. So now what I’ trying to do is have the host application in one solution and each plugin as single solution.
The problem here is that now, every time a change is made to the host application, we must be sure that anybody gets the latest compiled version for the development of his plugins.
Any idea on how that organizational issue can be solved?

PS: nice skin man!! 🙂

You’ve been kicked (a good thing) – Trackback from DotNetKicks.com

Write a comment