Recommendations for setting up a Visual Studio Solution for TFS

Over the past weeks I received a number of requests to explain how I typically set up my Visual Studio projects so they are easy to manage across a team that uses Team Foundation Server (TFS). I received another request from a client just this week and instead of helping him over the phone or paying him a visit and do it for him, I decided to write a quick document with instructions which eventually resulted in this article.

In this article you'll see how to create a multi-project solution in Visual Studio. I'll show you how you can use this structure to set up an ASP.NET MVC 3 application with a separate class library project for business logic and one or more unit test projects. However, you can use the exact same principles for other types of Visual Studio projects such as Web Forms, Win Forms, WCF and more. Over the past years, I found that this set up brings me the following benefits:

  • It has a clear structure, making it easy to figure out where to find or store something
  • It can be retrieved from TFS without any hassle
  • It allows for easy branching
  • It resolves most reference issues to third party assemblies

This is just my take at setting it up. If you find anything wrong, or have better alternatives to accomplish the same thing: feel free to speak up using the Comments section at the end of this article.

Without further ado, let's get started.

This document assumes a namespace convention for your projects and solutions of CustomerName.ProjectName.LayerOrAppName. The solution will be called CustomerName.ProjectName and each project then gets its own suffix explaining what it's used for. In this article I'll use CustomerName.ProjectName literally, but obviously you would substitute that for a real client and project name.

Setting up the Solution in Visual Studio

  1. Start Visual Studio (I am using 2010 but this applies to older and newer versions as well) and choose File | New Project.
  2. In the Other Project Types category click Visual Studio Solutions and then click Blank Solution. As the name of the Solution, enter ClientName.ProjectName and as the Location choose C:\Projects:


    Figure 1 (click to enlarge)

  3. Click OK.
  4. Close Visual Studio and open the Project folder in Windows Explorer (at C:\Projects\ClientName.ProjectName). Create a new folder called Main and then drag all of the ClientName.ProjectName.* files from C:\Projects\ClientName.ProjectName into this new main folder. Your structure now looks like this:


    Figure 2 (click to enlarge)

    This Main folder is used later for Branching in TFS. (This all feels a bit clumsy but I see no other way to create the solution with this name and store it in a folder called SolutionName/Main. Fortunately, this is a one-time operation.)

  5. Open the Solution in Visual Studio by double-clicking the .sln file in the Main folder.
  6. Right-click the Solution in the Solution Explorer and choose Add | New Project.
  7. In the tree on the left, choose a project type such as an ASP.NET MVC 3 Application.
  8. As the name of the project, enter ClientName.ProjectName.Web.
  9. As the location for the project enter C:\Projects\ClientName.ProjectName\Main\Applications:


    Figure 3 (click to enlarge)

  10. Click OK and finalize the project configuration.
  11. On disk, your solution now has the following structure:


    Figure 4 (click to enlarge)

  12. Right-click the Solution again and now add a Class Library project named ClientName.ProjectName.Lib. As the Location for the project, choose C:\Projects\ClientName.ProjectName\Main\Applications again:


    Figure 5 (click to enlarge)

  13. Add a reference to the Lib project from the Web project and perform any other necessary project setup and initialization. Add other projects as needed, storing each of them in the C:\Projects\ClientName.ProjectName\Main\Applications.
  14. [Optional] Right-click the Solution again and add a test project. Call it ClientName.ProjectName.Tests.UnitTests and store it in the folder: C:\Projects\ClientName.ProjectName\Main\Tests:


    Figure 6 (click to enlarge)

  15. [Optional] Create more test projects such as ClientName.ProjectName.Tests.Integration and store each of them in the folder C:\Projects\ClientName.ProjectName\Main\Tests.
  16. [Optional] In your test projects, add references to your various application projects (such as the Web and Lib projects).
  17. [Optional]: Create a new Solution Folder called Tests (right-click the Solution and choose Add | New Solution Folder) and then drag your test projects into this folder. This keeps all your test projects nicely packed together. Your Solution Explorer should now look like this:


    Figure 7

    while on disk your Solution should look like this:


    Figure 8 (click to enlarge)

  18. Finalize the configuration of your projects and do a full rebuild to ensure everything is set up correctly. Resolve any compilation errors you may have.

With this setup, all your projects are located in sub folders of the Main folder that contains the Solution File. This in turn makes it easy to manage the solution from a TFS point of view because all references between the various projects and assemblies can be resolved relative to the main solution.

If you ever have the need to add new projects, just follow the exact same steps: add applications under the Applications folder and tests under the Tests folder. When another developer then gets a latest version of the solution from source control, the new projects are downloaded automatically as well. Obviously, in order for all this to work, you need to add the solution to Team Foundation Server Source Control first, which is the topic of the next section.

TFS Initial Setup

  1. Right-click the Solution in the Solution Explorer and click Add Solution to Source Control.
  2. Choose a Team Project and click Connect.
  3. Choose the appropriate TFS Project
  4. As the name for the solution folder, enter ClientName.ProjectName/Main The /Main part is not a typo. In fact, it's very important, as it’ll create an additional folder in TFS which you can set up as main branch later.


    Figure 9

  5. Click OK.
  6. Your Source Control Explorer should now look like this:


    Figure 10 (click to enlarge)

  7. Right-click the Solution Explorer and choose Check In.
  8. As a comment, enter something like Initial Commit and click Check In.
  9. Open the Source Control Explorer, locate the Main folder for this Solution, right-click it and choose Add Items to Folder. Double-click the Packages folder and then press Ctrl+A to select all files and folders. Click Next and then on the Excluded Items tab make sure no files or folders are selected (select those that are and click Include Item(s)). Normally, you want to exclude files such as assemblies as they can be considered recreatable. However, the Packages folder contains third party libraries (by default, this folder is created by the Nuget Package Manager, but I now use Packages for my own third-party assemblies as well) that you do want included in TFS to ensure everyone gets the necessary files when getting a latest version of that folder from TFS. Click Finish to add the files. Then right-click the Packages folder and click Check In Pending Changes to add the files to TFS.
  10. Still in the Source Control Explorer, locate the Main folder for this Solution, right-click it and choose Branching and Merging | Convert to Branch.
  11. Enter a description such as Main Branch and click Convert.
  12. That’s it. From now on, other developers can get a local copy of this Solution simply by opening the .sln file from the Main folder. If they need a copy of the Packages folder as well, they can simply right-click it in the Source Control Explorer and choose Get Latest Version.

TFS Branching

After some time, development on the Main branch can be ready for a release. In order to let developers continue work on the Main branch while you prepare the release, you should branch the application. For example, you can branch of “Beta 1” and release that.

Note: in this model I assume the Main branch is where continuous development takes place, while releases are branched off this main branch. If you use a different branching model this section does not apply directly, but the principles remain the same.

In order to create the branch, follow these steps:

  1. Open the Source Control Explorer, locate the Main branch, right-click it and choose Branching and Merging | Branch. As the Target Branch Name enter something like $/Projects/ClientName.ProjectName/Beta1:


    Figure 11

  2. Click Branch

You now have two separate branches of the same application. Long-term development goes on in the Main branch while you can make changes to Beta 1 necessary for the release. In addition, bugs you find in Beta 1 can be fixed there and propagated to the Main branch or vice versa.
If you want to work on the Beta 1 version, double-click its .sln file in the Solution Explorer. Then enter C:\Projects\ClientName.ProjectName\Beta1 as the path for the application so your two branches end up side-by-side on your disk. In addition, you may need to get a local copy of the Packages folder in order to get all of the third-party assemblies and other files.

Hope you find these instructions useful. And if you have improvements or alternatives: post them below using the comments feature!


Where to Next?

Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article .


Consider making a donation
Please consider making a donation using PayPal. Your donation helps me to pay the bills so I can keep running Imar.Spaanjaars.Com, providing fresh content as often as possible.



Feedback by Other Visitors of Imar.Spaanjaars.Com

On Wednesday, November 23, 2011 5:07:59 PM Pat Brown said:
Thanks Imar,
I've been using your NLayered App ASP.Net 3.5 and have been looking for
a way to branch because I've got to start development on totally new functionality while maintaining the existing site.  This hopefully will be my solution.
On Friday, November 25, 2011 12:36:42 AM Bliek said:
Good article, Imar. One question though, you say: "In addition, bugs you find in Beta 1 can be fixed there and propagated to the Main branch or vice versa." Could you clarify the propagation scenario a bit further? Thanks.
On Friday, November 25, 2011 4:13:51 AM Imar Spaanjaars said:
Hi Bliek,

That's a bit too much to cover in a comment, but you can find detailed instructions about merging this TFS Branching and Merging guide: http://tfsbranchingguideiii.codeplex.com/

You want to get the complete package.

Cheers,

Imar
On Thursday, December 08, 2011 3:14:30 PM Sophia said:
Hi Imar,
setup is really clean and nice. I asked about you solution file at http://p2p.wrox.com/book-beginning-asp-net-4-c-vb/85584-visual-studio-sln.html, this article cleared all doubts that I had that time. But   my solution file is by default created at C:/Users/Sophia/MyDocuments/Visual Studio 2010/Project Name
and the real project is somewhere else say at F:/ProjectName/
So can we manage the same structure of solution in c drive and having project files in another drive.
On Saturday, December 10, 2011 10:19:00 AM Imar Spaanjaars said:
Hi Sophia,

I don't understand what you're asking, or why you'd want this. What's the point?

Imar
On Sunday, December 11, 2011 7:41:15 PM Sophia said:
I am just saying that is it possible to give reference of the project which is in F drive to the solution file which is in C drive

Thanks...
On Sunday, December 11, 2011 7:47:29 PM Imar Spaanjaars said:
Technically, yes. But the whole idea of this setup is to prevent exactly that. By placing your projects files in a folder below the one with a .sln file, things become way much easier to use.

I think with a TFS setup this may not even be possible. Haven't tried it because I don't have the need.

Cheers,

Imar
On Sunday, December 11, 2011 7:55:05 PM Sophia said:
You said => "By placing your projects files in a folder below the one with a .sln file, things become way much easier to use."

If I setup the projects like I said above then what problems may get raised, other than TFS setup.
On Sunday, December 11, 2011 8:05:55 PM Imar Spaanjaars said:
>> then what problems may get raised

The four items listed at the start of the article that are addressed by this setup.

If you don't care about any of those, this article is not for you and you can set up your project any way you see fit.

Cheers,

Imar
On Tuesday, February 21, 2012 3:06:40 PM Mike said:
Nice article, how do you set things up though if you have another solution that also needs to use the class library files that you have now located under the Main folder of the previous solution?
Thanks
On Wednesday, February 22, 2012 5:48:12 PM Imar Spaanjaars said:
Hi Mike,

Since you now have two solutions that require the same class library, I would take out the library from the main solution, give it its own environment (just as described in this article), and then reference it from both consuming solutions.

Cheers,

Imar
On Tuesday, October 22, 2013 5:05:37 PM Johann Alexander Quintero said:
Hi. I was looking for something like this long time ago. You said this works for any kind of Project. Do you know about LightSwitch? This setup can work for projects with LightSwicth?
On Wednesday, October 23, 2013 8:31:15 AM Imar Spaanjaars said:
Hi Johann,

Yes, as far as I know, this should also work with LightSwitch.

Cheers,

Imar
On Sunday, October 27, 2013 4:47:01 PM Shovra Das said:
It was a wonderful article. Thanks a TON!!
On Wednesday, December 04, 2013 3:54:38 PM Chris Walsh said:
Hi.

Your guidance is very reassuring as everything you want through pretty much goes along the lines that I use to set this up.

A point to note is that if I want to create other solutions that contain only a subset of the "all projects" solutions, I choose to place the SLN file in the same top level folder as the "all projects" solution.

My headache is getting TFS to pick up nuget packages.  Do you have any guidance on that?  Maybe a new article similar to the above that addresses nuget.

Thanks.
On Wednesday, December 04, 2013 4:15:04 PM Imar Spaanjaars said:
Hi Chris,

>> as everything you want through pretty much goes along the lines that I use to set this up.

That's good to hear ;-)

Unfortunately, I don't have guidance on how to let NuGet pick up the packages.

Cheers,

Imar
On Wednesday, January 22, 2014 4:24:27 AM Gogi said:
I am not able to add the comment
On Wednesday, January 22, 2014 8:11:37 AM Imar Spaanjaars said:
It seemed to have worked fine in the end.... ;-)

Cheers,

Imar
On Monday, October 26, 2015 9:57:03 AM Abhitalks said:
I am a bit confused now with the git support in Visual Studio.

I have an existing project with this folder structure:

- Company.App1
    - Main (folder)
        * Company.App1.sln
        - Dependencies (folder)
        - Packages (folder)
        - Company.App1.Core (library project folder)
        - Company.App1.Web (web project folder)
    - Release-V1 (folder)
        * Company.App1.sln
        - Dependencies (folder)
        - Packages (folder)
        - Company.App1.Core (library project folder)
        - Company.App1.Web (web project folder)
    - Release-V2 (folder)

Where "Main" is the current development branch, "Release-V1" contains the old version-1 branch, and "Release-V2" will be used to branch out for the current release.

Now how do I use "git" in Visual Studio to work this structure out with TFS online (visualstudio.com)?
On Tuesday, October 27, 2015 12:22:21 AM Imar Spaanjaars said:
Hi Abhitalks,

I am not a Git expert so I am afraid you'll have to look elsewhere for an answer.

Cheers,

Imar

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the QuickDocId of the document.

For more information about the Talk Back feature, check out this news item.