TFS and referenced assemblies - visual-studio

I have a project which is under source control using TFS. Actually, I have 2 solution in one TFS Collection. suppose the first solution is called SolutionA, while the second SolutionB. Each solution has it's own project in TFS. Now the problem I have is that, one of SolutionB's project should reference an assembly which is build in SolutionA. So what's best practices to achieve this?
Thanks

You have SolutionA that contains ProjectA, and SolutionB that contains ProjectB:
The two easiest approaches you can use for referencing ProjectA from ProjectB are:
Simply add ProjectA to SolutionB, and then ProjectB can use a project-reference to ProjectA. This means that you share the source code for ProjectA and make an independent build of it from within SolutionB as well as SolutionA. This will slightly slow down your SolutionB build (as you now always build ProjectA in it), but will allow you to make edits to the source code for ProjectA, and treat it as a normal part of SolutionB.
Build SolutionA and use a post-build step (or redirect the output path) to save the resulting ProjectA assembly (and its pdb and xml files, if you want to be able to debug into it) into a shared folder (e.g. C:\Libraries). Then use a file-reference from ProjectB to C:\Libraries\ProjectA.dll. This keeps your SolutionB build fast, and removes the need to have the ProjectA source code lying around, but means that any changes to ProjectA require a double build (first SolutionA to create the .dll and then SolutionB to pick up the changes to the .dll). (You can also opt to check in C:\Libraries to source control so another team could just provide a pre-built binary for ProjectB rather than you having to have anything to do with SolutionA yourself)
To clarify what I mean by Project-references and File-references: In your Solution explorer, right-click on the project's References folder and choose "Add Reference...". In the dialog box that appears, you can choose the tab "Projects" to list the projects in your Solution, and reference one of them (a project-reference). Or choose the "Browse" tab to browse to find a pre-built assembly .dll file (a file-reference)
(You could also install the assembly from ProjectA into the GAC, and then use the add reference dialog to reference it from the ".NET" tab, but IMHO this is a more complicated approach to use as you have more mess to clean up to remove the dll from your system)

There are a couple of options.
If the same team manages both solutions, I would highly recommend just putting them both in the same team project, Or just sharing the same source repository between both projects.
If they are managed by different teams, it might make sense to just give solution b a binary copy of solution a, and update it when a does a release.
If neither of those work, you could add a custom msbuild script in solution b which will get the latest version of solution a from source and build it, before building b. Something like this
My personal opinion is that team projects tend to get over used. I like to just have one team project per team and put all code in the repository there.

Guys, I found a better solution. When I create SolutionB, then I just add ProjectA in SolutionB without branching. To do that, just click File -> Source Control -> Add Project From Source Control.
Voila :-)

Related

How to make main project to use libs built from other projects in solution

Actually, question was set in the Theme of the message. But yet again,
i have Solution with 3 projects, two of whitch are Static libraries and one is Application. How my Application project could know from where to pull these .libs.
Yeh, i can do it from Linker->Input->Additional libraries, but i think there are must be other way if projects are in one solution.
There is another way, works on VS2010 and up. Right-click your EXE project, Properties, Common Properties, Framework and References. Click the Add New Reference button and select your project that generates the .lib. Repeat as necessary.
This does two things, it takes care of the Additional Dependencies linker setting, automatically adding the output of the library project. And it ensures that projects are built in the right order, normally something you'd have to with the Project Dependencies command. In your given example, with enough machine horsepower, the library projects will build concurrently. And the main project won't start building until they are both done.

Deploy solution which includes external projects

My project have the references to the bunch of projects from another solution (this solution also linked to own Git repository), but for convinience (to be able debug and modify them from one solution) I include these projects to my web-project solution which I want to deploy on AppHarbor. Maybe it could be said that these are sub-modules of my solution. But now I can't figure out proper way to deploy the solution on AppHarbor.
More structured description:
--Solution
------DeployedProject
------[SolutionFolderForExternalProjects]
---------Proj1ReferencedFromDeployedProject
----------Proj2ReferencedFromDeployedProject
Solution - linked to repo1
Proj1 and Proj2 - also belong external solution which linked to repo2, still ADDED to the repo1 explecitly -
git add SolutionFolderForExternalProjects/
How I should handle this sort of deployment?
AppHarbor really needs all dependencies pushed for us to successfully build you project. Generally, having one solution reference projects in some other random location on your local drive and checked into a different repository is probably not an optimal model. It's also bound to cause problems if some other person has to check out and build your code.
You should consider either combining the two solution structures into one repository (you can still have multiple solution files, see the AppHarbor solution file convention). Alternatively, package the respective dependencies up as NuGet packages and include them in your project using NuGet.

VS/MSBUILD: Copy output files of sub-project without adding reference to exe

I have a solution wich consists of main application MainProject and several plugin projects Plugin1, Plugin2 etc. Each of them is build in a separate project within Visual Studio.
For building the soution, I want all files of the plugins to be copied into the main application's output directory. But I don't want MainProject.exe to contain explicit references to the plugin dlls (they are loaded dynamically). Therefore defining project references for MainProjectdoesn't work.
I could use a post-build-step copying the files "manually" (as described in C# - Copy dlls to the exe output directory when using dependency injection with no references?), but since there might be multiple files for each plugin and they also change from time to time this solution is rather tedious to maintain (especially since I do have different build configurations, each of them producing different files). Also I would like to easily select, which plugins should be copied for a certain build.
What would be the best way, possibly involving custom MSBuild configuration changes, to do this?
See this link: http://msdn.microsoft.com/en-us/library/bb629394%28v=vs.100%29.aspx
When invoking MSBuild on the main project, if you could pass something on the lines of:
msbuild /p:CustomBeforeMicrosoftCommonTargets=[your custom msbuild file];PluginList=PathToPlugin1.csproj,PathToPlugin2.csproj
In your custom msbuild file, a target such as GatherInfo will get you the paths to output files of each plugin project. See this question for a sample: https://stackoverflow.com/questions/23346782/how-to-identify-files-needed-to-build-a-wix-project

package managers, project structure and migration

I have a solution with multiple projects in it, so for example say 10 testing related projects have a dependency on nunit. Currently my solution structure includes folders for Tools and Lib, so maybe the full nunit download is in Tools and just the dll in Lib.
I suppose any package manager (NuGet and OpenWrap being two I'm looking at) needs to create it's own 'known' location for packages. So whereas the old fashioned way of package management, after manually updating my Lib folder, I know every project that had a dependency on nunit just got updated.
But if I update with a package manager, I need to visit each and every project to ensure it is updated and pointing at the same reference, yes? And some dll's may not be found (am thinking unHAddins right now) so you aren't completely liberated from manual package management. Meaning migration to the latest updates isn't done until each and every project is updated by the package manager.
So I'm wondering if my understanding is correct, what the best approach to incorporating package management into a decent sized solution is - for example:
0) add to source control: NuGet 'packages' folder or OpenWrap 'wraps' folder
1) pick a dll (start with one that you beleieve has minimal dependencies)
2) pick a project (ideally with minimal dependencies that might break)
3) if OpenWrap, get the package you want into 'wraps'
4) for each project:
a) add reference to subject dll (manually if OpenWrap, NuGet will add for you)
b) fix compile error as needed
c) run tests
Does that sound right?
Cheers,
Berryl
To answer your questions, no you don't have to do anything with openwrap, all projects import all dependencies within a scope, so the update applies to everything.
I can't answer for the other package managers out there, but in openwrap, you'd add the /wraps folder in source control with the packages that got pulled when you added or updated them. The process would be to first add the package from a remote repository (or create one from your existing assemblies if there's not one available), and remove manually the references from /lib. In OpenWrap, we don't add the references to your csproj, we add them at build time, so if there's already a dependency in /lib, we won't add it. That means you can add all the packages, and remove the references one after the other, running your tests everytime.
Hopefully, this is a temporary problem until all dlls are available as packages, which will happen rather quickly.

MSBuild - can it work out project dependencies in a solution file? If so how?

I have an msbuild project which builds a SLN file from visual studio which holds all the projects in (about 70+ project), and a lot of the projects are dependent on each other meaning they need to be build in order - sometimes a developer forgets to set the build order manually in visual studio in the solution file causing the msbuild on a clean solution to fail as something gets built out of order/cant find a dll.
Is there a way for msbuild to take all projects and work out the dependencies and build the projects in order, if there is how do i do this? using an MSBuild task? With current tries it seems to just build in the order it reads the projects in - if i pass in a list of project files+paths.
Currently the only way i can think to solve this is a external app which scans the proj files and references and then manually creates a solution each time.. but this seems overkill for such a simple thing.
Anyone solved / seen this before?
How are you calling MSBuild? If you point MSBuild to the solution file, it should be able to work out the dependencies. If you point it to individual project files, then it won't be able to resolve any project references.
If you don't use project references you can still control the dependency order in a solution by using the "Project Dependencies" dialog to manually set the dependencies.
While Project Dependencies are hard to maintain and not shared across .sln files, Project References are honoured and do dictate the order consistently - see the ResolveReferences task in Microsoft.Common.targets.
ASIDE: A 'friend of mine' may 'during a refactoring' have accidentally stubbed out their Build Task and it's DependsOnTargets linkage to the Microsoft.Common.targets ResolveReferences task and ended up with ProjectReferences not being honoured in ways that sound like the question here. If you read some of the posts, you might get the idea that it's all mad shaky - it's not; the shaky bits are the Project dependencies, not the Project references.
See this excellent MSDN Blog article by Dan Moseley that really explains the topic, including some useful workaround strategies. (via this mildly related issue with building xUnit.net).
If all of your dependent projects are in the solution and you are using Project references, Visual Studio should manage the dependencies for your and build in order of that dependency list.
It sounds like you are not using project references. I always recommend project references.
This is an old question but the issue was most likely that projects in the solution used direct references to dependent DLLs (Add Reference > select Browse tab > select dependent DLL) instead of using project references (Add Reference > select Projects tab > select dependent project). With direct references, Visual Studio can't figure out the dependency chain. You must tell it by right clicking on the solution node and select Properties. Pick Common Properties > Project Dependencies to set the required projects. Mr. Klaus is correct but I wanted to document how to fix this issue.
While it is correct that MSBuild should observe the build order when you use project dependencies there is one caveat. It doesn't at present observe the reverse build order when building the clean target (as I have blogged about here). For regular build however it works nicely as described by others here.
I am using Msbuild 4 found at c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
It seems to solve the problem.
There is no Microsoft tool that will examine all the dependencies of your 70+ projects and generate a solution file with dependencies clearly declared for you.
You have to do that on your own by using 2 different methods:
Manually specify a dependency, for the solution, in visual studio.
Specify a project reference in the project file itself.
If you don't want to do that, then you will have to swallow the medicine and accept that you will to use an external tool to do that for you. Yes it's clunky but it can be made to work. If you check in your solution file to your source control you can mitigate these problems. As long as you have an active solution file to work with.
I at one point didn't, and I had 600+ projects in the build. So I wrote a tool (years ago) that would automate 99% of this work. It uses the .NET MSBuild API's to read the msbuild files (no recreating the wheel here with xml api's). It then examines outputs and inputs and generate a dependency tree which I can then do a few things with it:
Spit out a solution file.
Do a dependency sort (also a topological sort in academia), and spit out those projects in order they should be built (for a non-parallel type of build, which can be useful sometimes).
print out all sorts of diagnostic information about dependencies.
The only limitation I have seen with the tool is with a few crazy COM dependencies which are pretty sketchy anyways. Which I added a super simple work-around.

Resources