Ref: http://keithelder.net/blog/archive/2007/02/01/Structuring-Solutions-in-Visual-Studio-and-Team-Foundation.aspx
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:
http://www.cnblogs.com/http://www.cnblogs.com/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 structur