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

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!

Related

How should I structure my VSTS project folders?

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

Merging a common project with build variations in .NET MVC

I have a .net mvc site that should be published to a lot of different customers, and thus vary slightly depending on the target.
Is there any way to set up the core project structure, e.g. (simplified):
views
models
controllers
assets
bin
and make a merge at build time with whatever variations the current target might have. For example:
core project:
views
view1.cshtml
view2.cshtml
(removed rest of the folders for brevity)
customer 1 target:
views
view2.cshtml
view3.cshtml
desired merge result:
views
view1.cshtml (from core project)
view2.cshtml (from customer 1 target)
view3.cshtml (from customer 1 target)
The same rule should apply to controllers, binaries etc.
I would either use multiple projects, nuget, or use source control. I will talk about these ideas below, but in no particular order. By the end I may include a preference towards one or the other.
First idea I'll talk about is to use multiple projects. Create your base project, let's call it WebBase. Create your core website that you have talked about. Next create Customer1 website, if you create Customer1 as an empty website you will need to recreate the folder structures in WebBase or you cane create it the same as you did with WebBase and remove all the files(do this from within Visual Studio); either way you end up with the folder structure with no files. I would recommend keeping web.config,packages.config, Properties folder with AssemblyInfo.cs. Then you will add the files from WebBase, but don't just add them normally. For illustration's purpose let's do the Home Index View: Expand the Views Folder in Customer1, Right click on home, choose add, choose Exising Item, browse out of Customer1 and then in to WebBase/Views/Home and single click index.cshtml, now notice the drop down on the button? click that and choose "Add as Link". Now do this for all the files in WebBase! It will seem cumbersome to choose "add as link" every time, but if you just click add, it will copy the file and updates won't propagate from WebBase to Customer1! Also, you will see things like remove from project vs delete (with prompt about permanent deletion).
Second thought would be to create a nuget package for WebBase and you can than install it as a package, the benefit of this approach would be versioning and it would not require you to update every project with each little change. It would keep each project completely isolated. Down side is you would need to update each project individually to propagate changes globally. You would need to learn about nuget's nuspec file and how to include files and such. It isn't that bad, it is just XML. But you can indicate which files to include when the package is installed/updated.
Third would be source control, I know with git you can use submodule to include a seperate project (even from external repository). Which might be an option, or you could just create a WebBase branch, setup WebBase and then branch it off into each Customer's website. So create a branch called Customer1, start adding the custom customer things. Switch back to WebBase, create a new branch called Customer2... you are off to the races. Switch back to WebBase, make a global change and then merge these changes into Customer1 and Customer2 branches.
Okay, I will admit it, I would probably go with the third option. It gives you lots of benefit with little downside. It even get gives you history! If you aren't currently using source control... you should! You can install git on your machine and have the ability to check code in locally and you don't have to worry about an external repository (although I would recommend you have one as it gives you DR).
Either way, there are options available. But nothing like a single project with configurable file includes.
Good luck!
First thing that comes in mind (and probably easiest because it does not require any additional tooling) is to create core project with core functionality, views and controllers. And for each customer create separate project with custom views and controllers. Then for customer-specific project simply link all required files from core project. It can be a little tedious to link the files depending on the number, but seems doable.
Another approach could be to use tools like CAKE or FAKE, with the help of which you can script the entire build process the way you want, but I never tried doing such custom scripting myself.
Third option that I can work as well is to conditionally include files based on defined constant, but that will require editing *.csproj files. The code can be something like:
<Content Include="Views\View1.cshtml" />
<Content Include="Views\View2.cshtml" Condition="$(DefineConstants.Contains('CORE'))" />
<Content Include="Views\View2.cshtml" Condition="$(DefineConstants.Contains('CUSTOMER1'))" />
<Content Include="Views\View3.cshtml" Condition="$(DefineConstants.Contains('CORE'))" />
<Content Include="Views\View3.cshtml" Condition="$(DefineConstants.Contains('CUSTOMER1'))" />
Not sure how easy it will be to maintain it though.
I would probably consider to split the application into independent components/projects that will contain all functionality related to the component. The during the build compose components with FAKE based on what components are needed for particular client.
Your requirement is a great candidate for a custom Visual Studio Project Template.
I am thinking of preparing one big project with all the features you're deploying to whatever customer. This project also could be the trunk that you might update when a new feature or a fix is needed. Then, export the trunk-solution into a template. Then continue with VSIX project template and incorporate a wizard into it, to collect user input on a project creation. Based on the input take the appropriate action and add/remove the necessary files or enable/disable features as needed.
Or you might just keep the source files on the file system and organize them into the template on the fly - i.e., as a result of the user input during the wizard. At the end of the wizard, the template is deployed and ... voila.
What you need is super-admin section, where you could [de]activate different portions of the site, depending on customer.
There are some really good code answers here but if you're wanting an Automated Build system for every client and you have loads they could be a pain too setup.
When you could set up a script for Powershell that can do this
pseudo code
For each client site
download base code to code/
download this client's changes to code/ overwriting files
msbuild ....
copy client/ bin to build/client/
Delete code/
End For each
The answer to this question requires some innovation. So look at my solution please:
Set up the core project structure for the classes that cover Model and Controller files and then use them with technique named Add Existing Item As a Link which can share the followings:
App logic common to both apps, but not portable
User controls with no platform dependencies
Unfortunately that is not supported for razor views. So the easiest thing to copy shared views is to have multiple layout files like famous _Layout.cshtml file, one in each web app. You can also Compile your asp.net mvc Razor views into a separate dll to use them like a Reference (as shared views).
For the Assets, You can host all your style sheets (and some javascript if appropriate) from your main web application and access it from each web app.
The bin folder has core MVC dll files plus those that you add for using in your project and a projectName.dll file which will be created after building. You can simply Add/remove them by right clicking on References using Add Reference tool.

How do I build code out of a tutorial repo that has many examples (in Visual Studio/C#)

How do I build sample code, split into folders in a repo, from a class or tutorial, in Visual Studio?
So - I'm pretty much a noob at C#, I've gone through a lot of tutorials and browsed through some large C# projects from work and built them, and done some other minor things. I'm going through a course on writing testable code on Pluralsight. He has a public Github repo for the code examples, writing-testable-code. I connected to the repo and downloaded it okay into a local Git repo. I was able to download all the packages from NuGet and they are all showing as the version he used (a few have updates, but I figured updating might break things).
I can't figure out how to run this code, build it, or run the tests in it.
What I tried so far
My issue is - I open the solution, and there are a bunch of files and folders - each module/chapter is split into folders (i.e. Module1/Easy, Module1/Hard, Module2/Easy, etc.). I want to build the Module1/Easy folder, including unit test examples, and run the tests.
When reviewing Module1/Easy, it has 3 files that should build okay - the program.cs has a main() and looks like a console app, the Calculator.cs has a simple class, and the CalculatorTests.cs has unit tests built for Nunit. The solution has NUnit, Castle.core, and things from later modules (Moq, AutoMoq, Unity, Ninject, etc.). It didn't seem to have a VS runner, so I added Nunit3TestAdapter - the guy in the course has resharper installed, which I don't, and he was using the Resharper test runner, which would explain why he didn't include it.
I tried setting the "Module1/Easy/Project.cs" file the "Set as Startup Item", since it has a main and looks setup as a console app. However, running it (the "Start" button turned into a "Program.cs" button), it fails saying it can't run a dll. The tests aren't showing up in the Test Explorer like some other small projects I've built from examples.
What's the right way to do this?
I'm not sure where to go from here. On the Build menu is only a "Build Solution" and one about Code Analysis - I'm used to a lot more options here. It feels like I have to turn this folder into a project, maybe? I can always reinstall the packages - but what is the best solution here?
I've run into this before on other book, tutorial, or class repos, but finally decided to figure out how to get this one working. I appreciate any help!
Notes
I'm running Visual Studio Community 2017 at the moment.
I can post some of the files, but the repo is publically available, and not sure exactly what to post to help.
Progress from comments and answers
Per Biker-Dude's answer, I switched the project to build a console app rather than a dll, and now I get a compile-time error for having multiple entry points (i.e. every module and sub folder has its own Main() function and should probably be a separate project).
After #1, I removed all folders but one from the solution, it will then compile, run the tests, etc. - but I eventually want to be able to at least separately compile every sub-folder - what's the best way?
The problem must be that the project must have the output type set to class libraries. Browse through the solution tree and:
Select your class's project> right click > Properties > Application >
Output Type > Console Application/ Windows Application.
This should fix it, if the other things are set up properly.
With the help of BikerDude's answer and stijn's comments, I was eventually able to play around with this and get some things working.
First of all, don't try to exclude any folders in this situation, that will just make things worse! They will still be in your underlying folder/repo, just won't be showing up in your solution anywhere, and you won't be able to create a new folder with the same name (weird decision...). And you'll have to add them back in as individual files - I think.
The best solution (so far)
The best solution seems to be:
Create a new project for each buildable set of files in the solution (in my case, at least one project per "module" folder). I used the ".Net framework console app" project type (right click on the solution, use Add/New Project) to get things to work, but this would depend on the particular course or tutorial repo you downloaded.
Move the folder or sub-folder that has the files you want to build out of the main solution and into the new project - you can click and drag to move it.
Visual Studio will make an empty, pre-formatted file in your project that you likely have to delete - for .Net apps, this is the "Program.cs" file in C#. For one of my folders this file already existed, and I had to delete the new one in order to build. Another folder from a different module was setup more like a library and couldn't build standalone, but this procedure did get me to being able to build the files and that allowed the unit tests to show up in the test explorer and run the tests successfully (which was the main point of that module).
Go to the solution and right-click and choose "Manage Nuget Packages for Solution". As long as all the packages are installed for the main solution, then they will all show up in the list of Installed Packages (you might need to click on the "Installed" tab). You can click on each package in turn, then on the right you can checkmark the new project, and the "Install" button should be available - click it. Repeat for all the packages to install them all. Note that you can cut out some repetition here if you create all the projects you need first, then you can install all of them at the same time in this step (i.e. checkmark all the new projects at once instead of reopening the package manager each time).
You might have to fix the NameSpace - it should be consistent within the files/folders you transferred from the original solution, but if you add any new files to play with things, the Namespace for it will likely not match, and to see classes, etc. in the original files, you'll have to update your Namespace on the new files.
Per BikerDude's answer - After transferring everything to new projects, if you keep anything in the original project that came with the solution, it might not be trying to build the right type of item. You may be able to fix that by right-clicking the project, selecting properties, and adjusting the "output type", but it may not have the options you need. If it doesn't, just create a new project with the right type and transfer the files as above.
After following the above steps, I was able to build each new project I created, using the original files from folders that I moved. Mainly I just needed to build, which enabled all the unit tests that this tutorial/class was focused on, but this allowed me to build the console apps as well, when present.
Thanks for the help from all in pointing me in the right direction!

Add referenced projects into solution automatically

My situation:
I have a solution A with hundreds of projects,
Some of projects are class libraries and are referenced from other projects.
Now I want to create a new solution B which will consist of subset of projects of solution A. I start by adding the first pre-existing project into this new solution B. This project is referencing couple of class libraries from solution A. Therefore it is logical that these libraries cannot be found and I cannot build. Of course I could add all the referenced projects manually into the new solution B but that would take quite a long time, considering the total amount of projects that I need to add.
Is there some built in Visual Studio feature that can take care of this on my behalf? I.e. I will be offered an opportunity to import all the referenced projects at once and the B.sln file will be updated automatically.
I also have a ReSharper extension but I couldn't find such feature in there as well.
EDIT:
Some more detail on what I am trying to achieve. A.sln has lots of application projects and literally hundreds of class libraries. I want to create a new B.sln for one particular application project from A.sln and only add the class libraries that it is referencing, directly or indirectly... But the dependencies can go up to 15 levels deep so manually removing projects from original A.sln to create B.sln is really not suitable for me as I would have to carefully consider each one of the projects that I would be manually removing from the original sln file, subsequently reviewing the csproj files to find whether the application I am interested in does not indirectly depends on them via one of its direct references.
Copy paste your current solution file and start with it. Open it in new Visual Studio Instance. Remove your projects one by one. Instead of adding new projects, removing unnecessary ones will be more easy for you. As far as I know there is no such feature in Visual Studio as you want.
Removing will be more easy since projects are already there. Do not use Visual Studio to remove project but open sln file in suitable programmers notepad. Your projects are added to sln file as below lines.
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.Integration.App1", "..\Example.Integration\Example.Integration.App1\Example.Integration.App1.csproj", "{E3977144-AFBA-451D-894C-1F89AA008041}"
EndProject
Removing such lines will be more easy if your projects has naming convention.
The best way to port references from an existing project that I've found is to generate a template for that project.
On the File menu, click Export Template. The Export Template wizard opens.
Choose project template and move through the wizard
Click Finish. Your project is exported into a .zip file and placed in the specified output location, and, if selected, imported into Visual Studio.
Now, when you setup a new project for solution B. You'll be able to choose the project template from A and all the file structure/references are preserved.
Ref: http://msdn.microsoft.com/en-us/library/vstudio/xkh1wxd8%28v=vs.100%29.aspx

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
)

Categories

Resources