Allgemein Für Administratoren Für Architekten Für Entwickler Für Projektleiter Für Tester News Produkte Publikationen
X
Sven Hubert
Sven Hubert ist Senior Software Consultant, und MVP (Microsoft Most Valuable Professional) für das Visual Studio und Projektleiter bei der AIT und hat sich den agilen Prozessen wie z.B. Scrum verschrieben.

Sven Hubert

Extended Dependency Management with Team Foundation Server

Donnerstag, 11. November 2010

[Lesen Sie den Beitrag in deutscher Sprache]

There are many dependencies in software development projects. Build dependencies between components are of special interest. These must be managed during build, delivery and maintenance in order to keep track of them. Using Visual Studio Ultimate, you can visualize and analyze dependencies within solutions in Architecture Explorer. Many bigger projects however have multiple solutions which have to be build in a specific order and are developed on separate branches or even in different team projects. This article demonstrates how to use the extension points of both Visual Studio and MSBuild to make Dependency Management a first-class citizen.

Update

We’ve released a Visual Studio Extension – the”AIT Dependency Manager”. In the future, this will enable you to do extended dependency management without having to customize Visual Studio as described here. You can find the free tool AIT Dependency Manager under http://www.aitgmbh.de/DependencyManager.

What’s the problem?

Back to the Visual Studio solution mentioned above. A solution consists of several projects which might reference other projects or external assemblies. The figure below shows the basic structure of a solution:

SolutionTree_thumb

Figure 1: Solution structure

External references might be references to .NET Framework, 3rd party libraries or components built in-house – meaning deliveries from other teams or departments. this happens because of reuse or to enable work decomposition. Christian Binder is working with us on a whitepaper which will show the different options you have for handling these dependencies.

A branch-centric approach

One distinct solution option shall be demonstrated here using a basic sample.

We follow a branch-centric approach. A project is decomposed into different “areas” or parts (e.g. a platform and applications built on top of the platform). Every part is acting as a supplier for consuming parts – hence, has its own release cycles and is distributed as binaries via build results to the consumers.

The following graphic visualizes that:

BranchTree_thumb

Figure 2: Branching structure underneath a team project

The native function set of .NET Framework and TFS is lacking support to manage inter-solution dependencies across team projects. Some customizations and extensions are necessary to be able to mitigate this scenario.

ComponentDefinition.targets

Dependencies have to be modeled and stored somewhere. Because the dependencies are defined per solution, the solution is the place to store the definition. We define a file called ComponentDefinition.targets in the Solutions Items of the solution:

image_thumb111

Figure 3: File ComponentDefinition.targets as Solution Item

This file contains 2 essential parts.

  • An ordered list of solutions to be build, in case dependencies are loaded as sources which need to be built before the component solution.
  • The dependencies that have to be loaded whether it is sources from the repository or binaries from the build drop.

The different dependency types require different identification mechanisms.

  • Binary dependencies to 3rd party libraries (3rdParty)
    • Will be identified using a distinct network path
    • All files from the network share must be copied to the local output directory
  • Binary dependencies to in-house libraries or components (BuildResult)
    • Will be identified using team project name and build number
    • All files from the build drop must be copied to the local output directory
  • Source depdencies to other solutions (Source)
    • Will be identified via path and version in source control
    • Source control folder has to be mapped to the local workspace and a get operation has to be called

This causes the structure and contents of the ComponentDefinition.targets file:

image_thumb31

Listing 1: ComponentDefinition.targets contents

The file is in MSBuild format. The list of solutions to build can be specified as ItemGroup named ItemsToBuild (Lines 6-9). Solution Project2.sln is the actual solution inside the component of interest. Before building that, dependency Project1.sln of component Platform.Common has to be built (Line 7).

To be able to build, component Platform.Common has to be downloaded to the local client. Additionally dlls of component Platform.Compression are required in the output directory of the solution – which should be a central folder common for all projects. This is specified in ItemGroup Dependencies (Lines 11-25).

Hence, Platform.Common will be mapped and downloaded as sources (Line 13) into the local workspace in a specific version – e.g. a build label (Line 16).

Platform.Compression is provided as build result und will be queried using Team Project name, Build Definition name and Build number, and will be copied from the drop location to the local output path.

The described mapping and copy operations are executed by a custom MSBuild task named GetComponents (Line 4 in Listing 2) which is called in a target with the same name. Line 4 in Listing 1 imports the logic – so it has to be deployed to the local developer machine.

image_thumb41

Listing 2: Snippet of the central logic

The list ItemsToBuild is used in Listing 2 in line 12 to call MSBuild on all list items directly. This will build all solutions in their order. The script is simplified here; normally you would add additional parameters such as OutDir or Platform to configure the build.

Figure 3 has shown file ComponentDefinition.targets inside the solution. However, where is it stored in the team project or branch context? Basically it is stored next to the solution or underneath the component folder itself (here: Project2) in case there are many solutions which form the component. By using that approach, variants and stages of dependency lists can be managed stream-lined with branches. Figure 4 shows the sample inside Source Control Explorer.

image_thumb5

Figure 4: Location of ComponentDefinition.targets in Source Control

The workflow of a user is then like the following:

  1. Map component into a workspace in TFS mappen (subfolder of the component inside a branch – here: Platform.Base underneath branch Team Stuttgart)
  2. Open solution – here: Project2.sln
  3. Get Dependencies via ComponentDefinition.targets (runMSBuild)

Running ComponentDefinition.targets using MSBuild can be done via the command line. However, it’s more convenient to be able to call it from within the Solution Explorer context menu. You can do this in the following way:

Create new External Tools:

  1. Menu Tools > External Tools
  2. Add External Tool “Get Dependencies”:
    image
  3. Add External Tool “Build All” an:
    image_thumb9
  4. To add those tools to the context menu, open menu Tools > Customize… and go to the Commands tab.
    There select redio button “Context Menus” and select “Project and Solution Context Menu | Item” from the list.
    Add the commands “External Command X” and “External Command Y”, where X and Y are indices of the created tools from the list above(starting with 1).
    image_thumb11

The Solution Explorer context menu should now look like that:

image_thumb12

Figure 8: Context menu in Solution Explorer

Dependencies can be retrieved and built easily now. The ouput of the tools (MSBuild) is shown in their own output windows inside Visual Studio.

image_thumb13

Figure 9: Result in output window

All dependencies now reside in the local workspace. No more looking around for missing references or how to get the build successfully running.

Central Build Processes

During the development lifecycle, a local workspace as we’ve seen above is not everything that is needed. During central builds, all dependencies have to be available as well. With Team Foundation Build all steps described above can be run automatically.

The workspace template of the build definition contains the mapping to the component of interest:

image_thumb14

Figure 10: Map components in build workspace

The ComponentDefinition.targets file will be used as central Item to Build of the process (refer to figure 11). Using AIT Build Suite getting the dependencies can be incorporated be running the script with taret GetComponents after the download of the initial source code.

image_thumb15

Figure 11: Definition of build process parameters with AIT Build Suite

Visualizing Dependencies

This approach makes the team responsible for keeping their component definitions up-to-date. However, the decentralized definition files have to be visualized and controlled centrally. This can be done using Architecture Explorer and DGML – one option to visualize and analyse graphs such as the dependency graph.

Before getting into the details of the customization, let’s have a look into the native functions of the tools. Architecture Explorer comes with a Solution View which let’s you dig into the inner solution references and details.

image_thumb16

Figure 12: Solution View in Architecture Explorer

The queried information can be visualized in a DGML file by dragging and dropping the result nodes onto the file (refer to figure 13.

image_thumb3

Figure 13: Visualization of dependencies of a solution

However, this view does not provide any information about the branch or version.

Information about branches can be visualized inside the branch hierarchy  of Team Explorer. But this only shows branch and merge relationships between branches and nothing about dependencies.

image_thumb

Figure 14: Branch tree in Team Exporer

This gap in functionality needs to be closed. As mentioned above, Architecture Explorer seems to be the tool of choice. The extension point is Microsoft’s Progression API. Architecture Explorer provides a flexible provider model, which allows to place a dll containing an implementation class of interface Microsoft.VisualStudio.Progression.IProvider into the folder “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Providers”. When launching Architecture Explorer, the dll is loaded.

Using custom DGML query types, you can build a powerful tool for traversing and analysing graphs (refer to figure 15). Visual Studio queries directly TFS source control, e.g. loads ComponentDefinition.targets files into memory to parse and analyse them further.

image_thumb17

Figure 15: Custom Dependency View in Architecture Explorer

Every component can now be shown in DGML. Of course, all the dependency relationships are visualized as well.

image_thumb4

Figure 16: Visualized dependencies with version information

You can not only use the visualization functions of Visual Studio via DGML, Architecture Explorer provides some analysis features such as finding circular references in graphs.

image_thumb1

Figure 17: Analysis of circular references

Further Resources

Recorded TechEd 2010 Session: Extended Dependency Management using TFS 2010

Build Whitepaper: Company-wide build management with TFS 2010

Share components with TF Source Control (German Whitepaper): http://blogs.msdn.com/b/cbinder/…

TFS Branching Guidance: http://tfsbranchingguideiii.codeplex.com/

Summary

The sample described above only provides a small view onto a specfic options of handling dependencies across team projects and branches. Extensibility of Visual Studio, MSBuild and Team Foundation Server gives you many options. The provided solution is used in a similar manner at some of our customers.

If you need further details and code snippets, contact us. Feel free to send us an email.

About the Author

Portrait_100px_thumb7 Sven Hubert is consultant at AIT, member of AIT Team SystemPro Team and Most Valuable Professional (MVP) for Visual Studio ALM. His professional focus is on Application Lifecylce Management. Sven helps companies to introduce and customize Microsoft Visual Studio Team Foundation Server.
Contact him via Sven.Hubert (at) aitgmbh.de or leave a comment.

Verwandte Artikel:

Benötigen Sie Unterstützung bei der Software-Entwicklung und Architektur von .NET basierten Lösungen oder bei Einführung und Anpassung von Visual Studio / Microsoft Test Manager / Team Foundation Server?

Wir stehen Ihnen unter info(at)aitgmbh.de gerne zur Verfügung.

Tags: , ,

6 Antworten zu “Extended Dependency Management with Team Foundation Server”

  1. What to do with project dependencies? - But it works on my PC! sagt:

    [...] different and interesting approach has been proposed in Sven Hubert’s post “Extended Dependency Management with Team Foundation Server” on http://www.TFSBlog.de. He suggests using a custom MSBuild task and .Targets files that allows [...]

  2. What to do with project dependencies? - Richard Fennell sagt:

    [...] different and interesting approach has been proposed in Sven Hubert’s post “Extended Dependency Management with Team Foundation Server” on http://www.TFSBlog.de. He suggests using a custom MSBuild task and .Targets files that allows [...]

  3. MVP Summit 2011 – VS ALM stuff « Into Visual Studio Team System sagt:

    [...] dependencies, but this type of automated solution really rocks. Be sure to check out his blog article where he described his solution to manage dependencies with Team Foundation Server. If you [...]

  4. Raj sagt:

    Hi Sven,

    Do we have TFS-Dependency manager in Visual Studio 2010 (Professional)?
    What i need to install to use this feature?

    Please let me know.
    Thanks!

  5. Sven Hubert sagt:

    We’ve released a Visual Studio Extension – the”AIT Dependency Manager”. In the future, this will enable you to do extended dependency management without having to customize Visual Studio as described here. You can find the free tool AIT Dependency Manager under http://www.aitgmbh.de/DependencyManager.

    Regards,

    Sven

  6. consulting cafe sagt:

    Great post.

Hinterlasse eine Antwort