Editor's Note: The Following is a guest post by Visual Studio ALM MVP Jeff Bramwell
For those of you familiar with Team Foundation Server (TFS), you are no doubt aware that it ships with a great deal of functionality right out of the box. From work item tracking, to version control, reporting and everything else in between, TFS can handle almost any software development lifecycle (SDLC) methodology. As extensive as TFS is, you will still, no doubt, run into scenarios that are not inherently covered. To address these unhandled scenarios, Microsoft has provided broad extensibility throughout the product. The extensibility points in TFS include the process templates, reports, build automation, and, at a more granular level, the TFS Object Model. It is the TFS Object Model that we will be digging into in this article.
If you are new to the TFS object model, there are three basic steps that you must take to utilize the TFS object model:
Let’s take a look at each of these steps in more detail.
Before connecting to TFS, you must first decide if you need to interact with a specific TPC or with a TFS configuration server (which manages multiple TPCs). If, for example, you want to modify security settings for a TFS server instance, then you will need to connect to a TFS configuration server. If you want to retrieve a specific changeset from version control for a specific TPC, then you must first connect to the desired TPC.
The TFS object model provides classes for handling both of these scenarios. In fact, the methods and functionality provided by these classes are very similar because of a common class hierarchy. The following diagram illustrates the classes typically used to connect to a TFS configuration server or TPC.
The TfsConnection class provides common methods that apply to TFS configuration servers as well as TPCs such as the ability to get access to the various services provided by TFS. However, TfsConnection is an abstract class and therefore must be inherited from before it can be used. TfsConfigurationServer and TfsTeamProjectCollection both inherit from TfsConnection providing concrete classes which can be used to establish a connection to TFS. TfsConfigurationServer provides specific methods for connecting to a TFS configuration server (as the name implies) whereas TfsTeamProjectCollection provides methods for connecting to and managing a TPC. We will go into more detail in the examples below.
Once you have made your initial connection to TFS, whether it’s to a TFS configuration server or a TPC, all interaction is handled via the many services provided by the TFS object model. Some of the services are specific to the type of connection you have whereas others will work with either. Here is a list of the services provided by TFS 2010 and the type of connection(s) that can be used with them:
For example, if you want to query for a specific work item, you would need to utilize the WorkItemStore service. Notice that the WorkItemStore service is not available for an instance of TFS since work items are specific to a TPC. If you want to programmatically manage security, you can use either class since security can be applied at both the configuration server level as well as the TPC level.
Now that you know about the different types of connections you can make to TFS and the types of services offered, let’s put it all together.
The first step when creating any type of utility that is going to interact with the TFS object model is establishing a connection with TFS (whether it’s with a configuration server or TPC). With this being such an important step, there are myriad methods and helper classes that can be used to connect to TFS.
A connection to TFS is typically established when creating a new instance of either TfsConfigurationServer or TfsTeamProjectCollection (there are alternatives which are not covered in this article). As such, the constructors for each of these classes have multiple overloads allowing for various ways to establish a connection. There are also various helper classes that provide alternative mechanisms for making a connection, some of which provide visual user interfaces.
For example, you can:
We won’t cover all of these approaches in this article. However, once you learn one variation it’s fairly simple to implement another variation.
Before writing any code, you must first add the necessary references to our Visual Studio project. The references you add will directly depend upon the types of services you plan on interacting with. Most of the required assemblies that you will need to reference are located in the following folder:
32-bit à C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0
64-bit à C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0
To illustrate the process for setting up a connection, let’s create a simple application that will connect to a TFS configuration server as well as a specific TPC. Follow these steps to get started:
using Microsoft.TeamFoundation.Client;
5. In the Click event handler, write the following code, replacing the provided URIs with ones specific to your TFS configuration:
// Connect to an instance of TFS
var tfs = new TfsConfigurationServer(new Uri("http://tfsserver:8080/tfs"));
// Connect to a specific TPC
var tpc = new TfsTeamProjectCollection(new Uri(
"http:// tfsserver:8080/tfs/DefaultCollection"));
In these two simple lines you have established a connection to your TFS configuration server as well as a specific TPC (in the example above, the default TPC is used).
To obtain a reference to one of the many services provided by TFS, call the GetService<T> method provided by the TfsConnection base class where T is the data type for the type of service to retrieve. Let’s take the above example a step further and do something a little more useful such as querying the work item store. As you might have guessed, to query the work item store, you will need to make use of the WorkItemStore service. The following example illustrates the steps necessary to obtain a reference to the work item store reference and how to use that reference to query against the store.
To query the work item store follow these steps:
// Line 1: Get a reference to the work item store for the current TPC
var workItemStore = tpc.GetService<WorkItemStore>();
// Line 2: Build our query
var wiql = "SELECT [System.Id], [System.Title] FROM WorkItems WHERE
([System.TeamProject] = 'Demo') ORDER BY [System.Id]";
// Line 3: Query the work item store
var workItems = workItemStore.Query(wiql);
// Line 4: Display the results
foreach (WorkItem workItem in workItems)
{
Console.WriteLine("{0} - {1}", workItem.Id, workItem.Title);
}
Let’s take a look at this example line-by-line.
Line 1: Here, we are obtaining a reference to the work item store service provided by TFS. Specifically, this service only works with TPC references (see Table 1 above). Once you have obtained this reference, you can interact with the TPC’s work item store performing actions such as querying the stored work items, retrieving a specific work item, deleting work items, and more.
Line 2: For our example to work you must provide a string containing the WIQL (work item query language) query that you wish to execute against the TPC’s work item store. WIQL is similar in concept to SQL queries that you might run against relational databases such as Microsoft SQL Server. You use WIQL to specify the work item fields you wish to return, the fields (and conditions) you wish to filter against, and the sort order. Our example above provides a simple WIQL string that returns two fields (Id and Title) for all work items belonging to the Team Project “Demo” ordering the results by Id.
Line 3: This line is simply invoking the Query method of the WorkItemStore service to execute the provided WIQL query. This method will return an instance of WorkItemCollection which can be iterated through to retrieve the selected fields for each work item located.
Line 4: This section of code is simply iterating through each of the work items in the results displaying the work item’s ID and Title. A more elaborate example would most likely be returning more fields and have a more complex filter.
This article has only looked at one of the services provided by TFS and has exercised a fraction of that service’s capabilities. Covering all of the services and their respective features is out of the scope of this article so spend some time exploring the remaining services thinking about how they might apply to everyday scenarios in your development shop. Although the specifics for each of the services can differ greatly, the basic steps are the same – connect to TFS (a TFS configuration server or TPC), obtain references to the desired service(s), and write the code needed to solve the problem at hand. Keep in mind that Microsoft’s MSDN forums, documentation and various blogs are your key allies when writing code against any of the services provided by TFS. Check these resources out first when you start coding against a specificservice for the first time. With a little work, you can extend TFS to achieve results that may not have even been thought about when the product was first conceived or delivered.
Happy coding!
Jeff Bramwell has over 20 years of software development experience and is currently employed as an Enterprise Applications Architect by Farm Credit Services of America. He has been working with .NET technologies since the early pre-release days (mid 2000) and taught C# at a local university for three years. Having focused on Visual Studio and Team Foundation Server for the past few years, Jeff leads the Omaha Team System User Group and has presented on Visual Studio and Team Foundation Server at the Omaha .NET User Group, the Heartland Developers Conference, Tulsa TechFest, VSLive!, andothers. Jeff is a Microsoft Visual Studio ALM MVP and, as time permits, answers Visual Studio and Team Foundation Server questions in the MSDN forums and makes every attempt to post useful information on his blog at http://devmatter.blogspot.com/. You can follow Jeff on twitter at twitter.com/jbramwell.
I would like to thank you for the efforts you made in writing this post. I am hoping the same best work from you in the future as well.
<a href="www.rdplapps.com/.../apparel-manufacturing.html">garment retailing software</a>