How should I structure my VSTS project folders? - c#

I am trying to understand how I should structure my TFS/VSTS Folders and local workspaces/folders/mappings, etc. I am looking for a best practice approach I can follow along.
Currently I have got two projects within my VSTS account:
$/ProjectA
+- Main
+- ProjectA
+- ProjectA
+- ProjectA.sln
$/ProjectB
+- Main
+- ProjectB
+- ProjectB.sln
As suggested by this MSDN link I have created a 'main' folder at the root of the project. So I am able to create branches in case it is needed later.
Please note that ProjectA has an additional folder called ProjectA, which was created by Visual Studio, when using the new project wizard and checked "Add to source control".
Regarding ProjectB: First I have created the solution without adding it to source control. But then later moved the solution into the folder that is locally mapped. And afterwards opened the solution and choose "Add solution to source control".
I have got one workspace, called: "MyWorkspace". The path mappings within this workspace are set as follows:
$/ProjectA ==> C:\Dev\Projects\ProjectA
$/ProjectB ==> C:\Dev\Projects\ProjectB
NB: Both projects have nothing to do with each other.
Questions:
How should I structure my folders within the VSTS project? At which level should the .sln file reside?
How should I structure my local folders and the mappings?
Should I use one workspace containing all project-mappings or one workspace per project? Or should I even have multiple workspaces per project as suggested by some blogs? (sorry cant find the link anymore)

I agree with Flater, This question is completely subjective.
However MSDN provided the suggestions on using the server-side structure and client-side structure, also Branched Folders and Workspaces explained.
Strategies for Solution and Project Structure
The three most common strategies used to structure solution and
project files are:
Single solution. If you work on a small system, create a single solution and place all of your projects within it.
Partitioned solution. If you work on a large system, use multiple solutions to group related projects together. Create solutions to
logically group subsets of projects that a developer would be most
likely to modify as a set, and then create one master solution to
contain all of your projects. This approach reduces the amount of
data that needs to be pulled from source control when you only need
to work on specific projects.
Multiple solutions. If you are working on a very large system that requires dozens of projects or more, use multiple solutions to work
on sub-systems but for dependency mapping and performance reasons do
not create a master solution that contains all projects.
In general you should:
Use a single solution strategy unless the resulting solution is too large to load into Visual Studio.
Use multiple solutions to create specific views on sub-systems of your application.
Use multiple solutions to reduce the time it takes to load a solution and to reduce build time for developers.
Please refer to below links for details:
Strategies for Solution and Project Structure
Structuring Projects and Solutions in Team Foundation Source
Control
In some cases, you can create multiple workspaces to isolate and switch among the changes you are making in different branches.
If you’re using local workspaces, then you can see some performance benefits by switching to using “one branch == one workspace”. Please refer to phkelley's blog for details:
TFS Version ControlUsing multiple workspaces with Visual Studio
You can also reference jessehouwing's answer on how to use the workspace: https://stackoverflow.com/a/48355207/7466674

Related

How is dirs.proj used?

I'm afraid I may be asking a really dumb question, but I can't seem to find anything that makes this clear. I usually work on smaller applications but am now working on a larger one with several assemblies in a baseline framework and several assemblies for a product line domain (with more to come). I would like to manage the build by configuring MSBuild. I've done a lot of online research (specifically with several MSDN articles I found) and now feel knowledgeable enough to be dangerous.
I understand that in csharp the *.csproj file can be unloaded and modified with properties, items, and targets to control the build process. I also understand that I can import my own targets file to help separate and organize. In this link though (https://msdn.microsoft.com/en-us/magazine/dd483291.aspx) a multilevel project build is organized with node-level dirs.proj files. This is confusing to me and has raised several questions I can't seem to find an answer to:
What is the difference in a *.proj and *.csproj file?
Can a *.proj be setup in VS to load on Build with F6 or does using this require use of the command prompt only? (i.e. "msbuild dirs.proj /t:Build").
Does dirs.proj load automatically? If so, my study-by is not working correctly, yet it does with command prompt.
Or am I overlooking something all the way around with "dirs.proj" Maybe it's just a substitue name for one of the project *.csproj files? If that was the case though there wouldn't have been a need for the root node's dirs.proj which from what I can tell doesn't have an actual project associated to it.
Anyways, I've seen dirs.proj mentioned in several forums regarding issues, but no where can I find how it's loaded or used in VS (outside of manual command prompt building which seems unreasonable if this is used to organize the build but the build won't really take a huge amount of time). I'm hoping someone can help me achieve that a-ha moment with this.
Thanks in advance.
Dirs.proj is an MSBuild convention typically used when dealing with very large source trees (> than 20 projects). I've worked with Microsoft engineers at a previous company and the dirs.proj convention appears to be one that Microsoft developed and uses internally to manage very large source trees.
A very good implementation reference for this is the Python Tools for Visual Studio project on CodePlex GitHub.
The link you shared by Sayed Ibrahim Sashimi is a very good explanation of the reasoning behind the msbuild paradigm, but it doesn't do a very good job of showing a practical example of how it works. The Python Tools project is an outstanding reference for this.
The idea behind using this paradigm is simple. I'd wager a guess that most .NET software engineers work on somewhat limited-scale projects that don't deal with more than 5-10 projects at a time, and they manage these projects in Visual Studio via Solution (.sln) files. They may even instruct their build system to run builds on the .sln. This works fine until you start thinking about scaling your product into or combining it with something larger, such as a platform with many, many projects. Solution files are not MSBuild files and as such they are not extensible like MSBuild is and they suffer massive performance penalties when dealing with large numbers of projects.
From an MSBuild perspective, dirs.proj stands in for Visual Studio .sln files. The difference, however, is that dirs.proj don't just include .csproj (and the like) as .sln do, rather, they can include source subtrees (e.g. other nested dirs.proj). So, building the root dirs.proj can result in the entire source tree being built, or building a nested dirs.proj will result in that subtree being built.
Therefore, the paradigm encourages you to look at your source as a series of interdependent nodes organized into features or product areas. That way, engineers can work on different source subtrees in very large projects without having to deal with the entire source tree, as you would have to with a VS solution.
Using this paradigm also carries certain benefits that don't come with .sln files. For example, if one project references a project from another, separate subtree, msbuild will build that reference first, automatically. Additionally, your source nodes can carry their own build settings, allowing them to be built dynamically using different build settings based on build scenario. For example, under one scenario a SharePoint source subtree needs WSP packaging, a C# subtree needs to be built without .pdb, a DB subtree needs to generate dacpacs, and the entire source tree needs to sign their assemblies using myCorp.snk and set build output to the $(buildRoot)\Output directory.
dirs.proj aren't opened via visual studio - they're built on the command line using msbuild. The only pain point is that the files have to be hand-curated.
So, long answer short take a look at the Python Tools project and see how they're using dirs.proj. Note how the entire source tree has common settings managed by Common.Build.settings, and how msbuild properties in this .settings file are used in the various .csproj files.

How to add projects into the solution that already in Source Control?

I have two C# projects in TFS and I want to add them to another solution (that is in TFS as well), how to do this correct?
Tried to check out these projects and open the target solution > click "Add" > "existing project" but VS doesn't recognize this projects as they are under Source Control.
All I need now is:
1) Get copies of 2 projects that are already in Source control
2) Add them to my solution
3) Make changes in these projects
4) Check-in changes without affecting the original versions
Let's call your two projects your framework. You should branch your framework and then link in your new solution to the appropriate branch.
Branch.
In Visual Studio, Team Explorer, browse your code collection
then right click on your framework source root folder and select "branch" .
Then checkin your new branch.
Link
In your new solution, click "Add Existing project..." and select the projects from the branch you just made.
The branched code basically is a full copy of your framework source code. But this copy is logically linked to the original one (for the TFS system). Nothing will be altered in the original one when you alter the branch, but you can merge selected changeset if you wish.
Folder structure
There are many possibilities about how to structure your TFS collection. My advice is to keep your main developping framework code in a Trunk folder and to have, at the same level, a Branches folder with all the versions in it. In the image above, there is only one branch made yet (named after a released version of my project to do hot fixes if needed, but this is just an example).
Merge
Then, you can merge changes if you want from the branch to the trunk (no obligation, just to avoid manual-error-prone code copy).
The documentation is here.
Sharing of code between different solutions is an ati-pattern that should be avoided.
If you have two projects that are required in more than one solution you should build and version them independently.
1) Split the two projects out to a new solution and folder structure.
2) Build and version your two shared assemblies
3) package both assemblies as Nuget packages and store on a network share or ProGet server
4) change the references for your two other solutions to use the new Nuget Package
5) create an automated build to refresh the Nuget package as you change the code.
You then have a shared component that you can make deliberate changes and deploy to your shared location. Each solution that takes a dependency will then notify you when the code is changed.
If you want to have two independent copies of you projects, then Askolein solution is your best bet.
However, if you want to reference the same projects from many different solutions then I think the following should work (some of it you listed already):
in your workspace map and download directory that contains all projects and location of both solutions. So if you have $/tp1/solution1 for existing solution $/tp1/solution1/proj1 for project and $/tp1/solution2 for new solution then you map $/tp1 and best download all files under it
now open solution2 (the one that you want to changes) and click Add->Existing project. You should be able to select projects as they exist on your local disk. You may need to "Add solution to source control" just to add your solution file. However projects are already in TFS and all your operations should not change their content (projects may be in many different solutions)
Good luck!

Good practice for working with multiple solutions in Visual C# Express

Background: My team is made up of 3 fairly inexperienced developers. We are developing in-house software for our company. Currently we have a number of smaller and separate solutions. Many of these are interdependent. Currently these depencies are made by referencing the output dll's in the respective release-folder. Updates are pushed around by manually rebuilding dependent solutions.
Example:
Solution A uses features of solution B. The connection is made having Solution A referencing ...\Release\B.dll . Changes to B propagates by building solution B, then building solution A and so forth.
This has worked okay before, but now we are moving from a manual (mind numbing) "version control system" (folder1, folder2, folder2New...) to using a proper one (git).
It seems that versioning the .dll's is not recommended. This means that every time someone wants to build a new version of A, he also needs to build B (and maybe 5 other solutions) in order to have the latest version of B.
I'm thinking that there must be a better way to do this.
I've been looking at combining the relevant solutions into one master solution, but I can't figure out how to do this in Visual C# Express (which we are using).
So at long last the questions:
Is having a master solution that builds everything the way to go?
-- it seems so from MSDN but I can't figure out how to do this in Visual C# Express 2008, which leeds me to
Is this even possible in Visual C# Express? If not, what is a
good way of managing the problem?
Edit Thanks to all for the great suggestions below. Here's a summary of what I ended up doing.
In short the answers to the questions are: "Yes" and "Sort of, but mostly yes". I implemented as follows: In order to get an idea of the dependencies, I did as suggested below, and drew a map of the binary products, with an arrow pointing from the dll's or exe's name to all of its dependencies.
For each project, I opened its corresponding solution (since at first there was one solution pr project). I then added the projectfile of each dependency in the tree structure revealed in the graph (by right-clicking the solution in solution explorer), so that also dependecies's dependencies and so forth were included. Then I removed the old references (pointing directly to the .dlls) and added references to the projects instead.
The important result is:
When a solution of a project is built, all it's dependencies are built with it, so that when deploying, you know that all the build products are automatically of the latest version.
I would create a new solution and add all of the projects that relate to each other to it. You can group the projects from each of the original solutions by putting them in different solution folders within the new solution. This way, when you build a project, all of the projects it depends upon will also get built. It also means that all of your projects will be built using the same configuration (i.e. Release or Debug). This means that all of your projects can be built in Debug, not just the top one in the dependency tree while everything below it is a Release assembly. Makes debugging much easier.
I have Visual C# Express 2010 and when I create a new project, it automatically creates a default solution. If it's visible, then you can right-click on the solution and choose Add>Existing Project.
If the solution is not visible, (I seem to remember this problem in C# Express 2005/8), then you can add an existing project via File>Add>Existing Project. The solution should be visible now.
In terms of speration, what I usually do is this:
Everything that must be built together should be in one solution, and these should be projects and not DLL's. I try to live by The Joel List, where you should be able to build your project in one step. If it is one deployable unit, then there should be one solution. All of my projects are built on a build server before they can be deployed, so everything should be in the solution that needs to be built.
Guys sometimes put the WCF services project and the clients in the same project for easy debugging, but it depends on whether you want to deploy client and server independently. Usually for bigger projects I separate them.
Lastly there's one exception. We have a central common library that is used by different teams. If it's included in different solutions, and one team changes something, we end up breaking the other team's builds. In this case, we create a single solution that has all of the library projects. These get built to DLL's that we store the versions of. We treat these as a framework that the other solutions can use. E.g. Team A is using CommonLibrary 1.1 and Team B is using CommonLibrary 1.2.
You need to think of Solutions as just "groupings of projects" - the projects are what are actually "built", not the "solution" (well, that's not entirely true, the solution is turned into a "metaproject" that references the contained projects, but its close enough to the truth)
If you have interdependencies between solutions, I would suggest drawing all the projects on a big whiteboard, then draw arrows representing the dependencies from project to project. Once you've done this, you'll be able to see at a glance what the appropriate "groupings of projects" make sense. Those become your solution files.
For example, if you have projects A, B, ..., F, where:
A depends on B
B depends on C
D depends on C
E depends on F
One possible split here would be solution 1 with projects A, B, C, D and solution 2 with projects E, F.
I would come up with a common area to push all dlls. My company uses the "R" drive, which is just a LOCAL (not network so no one can touch another persons folder) mapped folder everyone has. Each solution will build to this. Right click a project, properties->build and change the output. Or you can add a post build command to push the dll there. After that, have all of your projects reference this location.
Once this is done and everything is pointing at the same place, you can even add different combinations of projects to different solutions. If a developer only wants the ui projects, they can open a special "ui" solution that is a subset of the whole.
Here is a post build event that I use in my project properties->build events
rem when building on local workstation copy dll to local R:\
if '$(BuildingInsideVisualStudio)' (
xcopy $(TargetDir)$(TargetName).* R:\Extranet\$(TargetName)\1.0\ /Y
)
rem if "Enterprise" build then copy dll to Corp R:\ drive and to Build Machine R:\
if '$(Reason)' == 'Manual' (
xcopy $(TargetDir)$(TargetName).* \\folder\$(TargetName)\1.0\ /Y
xcopy $(TargetDir)$(TargetName).* R:\Extranet\$(TargetName)\1.0\ /Y
)

How can I share common style information (css, images, etc.) across MVC sites?

It's dead simple to share functionality across multiple MVC projects. You just put the code into its own project and reference it in as many solutions as your heart desires. Clean, standard, glorious.
Is there any means to do this for styling code? I'd like to have our common CSS files, the ones that give our applications a similar look and feel, in just one place. Right now I have to spawn new copies for every new application. Thus if something needs to be fixed, it needs to be fixed a dozen times in a dozen places.
Has anyone else dealt with this? I can't separate out the CSS files into their own project, nor do I really want to have a web application that's just css sitting somewhere so all of the applications can use the files remotely via fully-qualified Urls. Is there a TFS trick you can do with source control to link the files together? Is there something I haven't thought of?
Here is the "dead simple" solution for sharing web resources between projects without using CDN, LESS, SASS, NuGet, etc:
Create common Solution Folders containing the resources to be shared, or simply designate one of the projects to be the master.
Use "Add as Link" to add the shared resource files to each project as needed.
Add an AfterBuild task to each project file that will copy the linked files to project folders. This is only needed so that Visual Studio test/debug (F5) will work locally.
If you need the details on how to do this, keep reading.
Configuring Solution Folders for the Shared Resources
** Note that if you're simply going to share files directly from one project to one or more additional projects then you can skip this step.
Visual Studio solution folders do not have to reflect physical file system folders, but doing so will help preserve your sanity. So first create the folders on your local file system and copy the resource files into them. The new folders should be located under your solution folder. For example:
\MySolution
\Common
\Images
\Scripts
\Styles
Back in Visual Studio, right click on the Solution Items folder and use Add Solution Folder to replicate the new file system folders.
Next, add the files to the new solution folders by right-clicking each folder and using Add Existing Item to add the contents of the folders.
Add Shared Resources as Links
For each project that will use the shared resources, right-click the project folder and choose Add Existing Item. Browse to the common folder, select the desired files, click the drop-down arrow next to the "Add" button and choose "Add as Link".
You may get a source control warning about adding files that are outside of the project directory structure, but this can be ignored since the linked file will be under source control at its source.
Add an AfterBuild Task to Copy Files
When you publish the application to a server the linked files will copied to the project folders to which they are linked and everything works as expected. However, in the development environment the linked files do not physically reside in the project folders. So when you hit F5 to test your application in VS, the shared resources will be missing.
The simple solution is to add an MSBuild task to copy the linked files from their source after each build. This needs to be done to for each project that contains the shared resource links.
Right-click the project and choose Unload Project. Right-click the project again and choose Edit <ProjectFileName>. Scroll to the bottom and add the following (just above "</Project>"):
<Target Name="AfterBuild">
<!-- Copy linked content files to local folders so that they are available in the debugger.
This is only an issue when running the application locally. The linked files should
be automatically published to the correct folder when publishing to a web server. -->
<Copy SourceFiles="%(Content.Identity)"
DestinationFiles="%(Content.Link)"
SkipUnchangedFiles='true'
OverwriteReadOnlyFiles='true'
Condition="'%(Content.Link)' != ''" />
</Target>
** Copy task adapted from this link in TheCodeDestroyer's answer.
Save the project file then right-click and choose Reload Project.
Why not just have one site host that base styling and the other sites reference those styles? I don't see anything wrong with this.
You could create a CDN application of sorts to do this, too.
MVC App #1
<link src="~/css/styles.css" />
MVC App #2
<link src="http://mvcapp1.com/css/styles.css" />
Well, I don't know much about asp.net development, so forgive me, if it's not the case, but
If resource files in your project have Build Action set to None or Content and Copy to Output Directory set to Copy..., you can easily create the Class Library type of project and place all the files there (preserving the paths), and then reference this "Class Library" in every project that needs the files. Every file will be copied to every referencing project on solution build.
For Embedded Resource build action it will also work, but, you'll need to find a way to specify the assembly, which contains these files (because it will differ from Assembly.GetEntryAssembly).
Personally I don't like or want the CDN solution as if you have many pages they depend on CDNs 100% up time. After some research I found this solution which was perfect for my use I hope whoever will look for an alternative this is one of them:
http://mattperdeck.com/post/Copying-linked-content-files-at-each-build-using-MSBuild.aspx
1 - Look into CSS template systems as mentioned :
SASS-Lang
Less
http://css-tricks.com/sass-vs-less/ (really good article to start, many related items to in his related posts widget)
These allow you to code your stylesheets in organised manners. You can quickly add dynamic configurations and global changes easily.
2 - Developer your own CSS global listing system :
If you prefer not to use the above CSS stylesheet system. Example
//cdn.com/assets/css/reset.css
//cdn.com/assets/css/main.css
//cdn.com/assets/css/page_home.css
//cdn.com/assets/css/page_cart.css
even...
//cdn.com/assets/global/form_styles.css
//cdn.com/assets/global/global_shortcuts.css
In these, the same form padding, table and tr and other padding rules. Example
.black{color:#000 !important}
.right{float:right}
.left{float:left}
I know I sound like framework mentality but it works..
You can quickly alter the global to ensure all pages are updated.
The CDN storage and compass suggestions are valid too. You see storing on a CDN will save the headache of worrying about application failure / speed / load.
Your application can simply be like
/cloud/servers/settings/global/db
/cloud/servers/settings/global/librarys
/cloud/servers/settings/global/css_config.php (example)
/cloud/servers/1/webapp.com/
/cloud/servers/1/webapp.com/model
/cloud/servers/1/webapp.com/view
/cloud/servers/1/webapp.com/view/themes/tpl
/cloud/servers/1/webapp.com/inc
/cloud/servers/1/webapp2.com/
/cloud/servers/1/webapp2.com/model
/cloud/servers/1/webapp2.com/view
/cloud/servers/1/webapp2.com/view/themes/tpl
/cloud/servers/1/webapp2.com/inc
//cdn.com/assets/css
3 - Configuration of Approach
I personally think that the question should be about the approach of your overall development methodology. Having CSS sit on a CDN application, or having a CSS on a separate server which syncs to the CDN for production live mode is a good idea - keeping it separate and maintaining it via a stylesheet language is even better. You can then quickly use skins, css libraries, image libraries and more. Keeps things organised, faster and much better and ENJOYABLE to look at and take pride in coding with.
Keeping it and using a better system is what is needed. You should use manual and the classical approach of a folder structure IMO. You won't have to worry about responsive application design for mobile/tablet and other bearing issues with updating one CSS line for all the apps or even single apps - even languages, and dealing with multi site development teams.
JUST MY HUMBLE OPINION
Would also strongly recommend a CSS stylesheet language, sure many people hate them. But they are becoming quite useful, especially SAAS it's not a hype like NodeJS was.. it actually works. And does wonders. Look at TopShop, GorgeousCouture.. Arcadia sites.. multiple languages, multiple currencies.. servers and teams working on the same cross brand and several applications for each store..
We had the same problem and for our purposes we put all general CSS/JS/Images/Layout View into NuGet package and reuse it from every application where we need it. It perfectly works for us.
If you're open to using Sass, Compass extensions might be just what you need.
http://compass-style.org/help/tutorials/extensions/
An extension, when bundled as a gem, allows you to easily include the styles contained within the gem from anywhere on the system that has the gem installed. I recently used this in my latest application (a specialized multi-user CMS where each user has their own subdomain that has a customized layout, but all of the components/widgets have the same styling throughout the application). Setting up a new subdomain's styling is as simple as running a single command and customizing the template I've setup that has a skeleton of a simple layout.
Compass extensions can be used to hold images and JavaScript files as part of a template, but deployed files aren't automatically updated like the styles are (templates from a Compass extension differ from the stylesheets, as the templates are for copying and the stylesheets are for importing).

Which visual studio solution type is right for me?

I currently have a program that i wrote that is divided up into 3 separate solutions.
Front end (all display related stuff)
Parsers (multiple (39) projects that each create a dll to parse specific data)
Globals (multiple (5) projects that each create a dll that is used by projects in the parsers solution, and by the front end).
Requirements -
Both the Front end and Parsers require the globals dlls to exist at compile time, and used at run time.
The Parsers dlls are loaded at run time using assembly.LoadReference.
Development is: C:\projects\myProg
deployed location is: C:\myProg
My problem is that I have been going back and forth with issues dealing with project dependencies, where to point to for my globals dlls. Do I point to the deployed location or the developement location, and if so, release or debug?
So I started looking up the different solution types, and I'm wondering if I should set up a partitioned solution, or a multi-solution for my particular situation.
Add all the projects to a single solution.
Change any references between projects into "project references" rather than direct references to dll files. This will fix a lot of dependency issues.
If you have any "library" files that are not changed often, then you can optionally move them into a separate solution. The output of this should be "prebuilt" release dlls that you can then reference from a standard location in your main solution (the best way to do this is to add a post build step that copies the output to your development "library binaries" folder. That way, the build process is not changed, you simply add an extra step to get the files where you need them, and you remain in full control of the build process). This works well, but is a pain if you need to change these prebuilt dlls often, so it's best only used for fairly static parts of your codebase.
Finally, consider merging many of your projects into a single project/assembly. The killer on build times is not the amount of code, it's the number of assemblies - on my PC every project adds a pretty constant 3 seconds to the build time, so by merging small projects I've saved quite a bit of build time.
Since those 3 are all part of the same system, it will probably be easier to have a single Solution with each Project added to it.
NOTE: You do not need to move anything from their current locations.
Just create a new empty solution and do a right-click Add > Existing Project... for each project you want to be a included, they will remain where they are on disk, but will be opened together.
The current ("old") solutions will be available as well, just as they are.
Also keep in mind that if you are editing the same project in two instances of VS at the same time, it will bug you about reloading the source code when a change is made and saved.
Most importantly, having the projects in the same solution will allow you to add references between them, rather than the DLL files.
why are they scattered into separate projects, Combine the Parses and globals into a single assembly. keep the UI assembly separate and as simple/small as possible.
Let's say you have a good reason for having so many projects (example: different amount of parsers available for different licenses of a product).
Managing dependencies in visual studio is made easy:
Right click your solution node
Select "Project Build Order..."
Make sure that every project does not need a project beneath it in that dialog.
About "where to deploy": visual studio does it well by default. If you're in debug, it will output to the debug folder of your solution, likewise for release.
HTH.

Categories

Resources