Introducing the TfsConnection, TfsConfigurationServer and TfsTeamProjectCollection Classes

If you are familiar with the TFS 2008 client object model then I am sure you have interacted with the TeamFoundationServer object that lived in the Microsoft.TeamFoundation.Client namespace.  It is the starting point for all communication with a 2005 or 2008 Team Foundation Server.  Due to the architectural changes that have been made for TFS 2010 we found that having a single class called TeamFoundationServer did not provide the correct starting point for communicating with a 2010 Team Foundation Server.  Because of this, the TeamFoundationServer class has been deprecated and it has been replaced by the TfsConfigurationServer and the TfsTeamProjectCollection classes.

In order to understand why we made this choice you should first understand how the Team Foundation Server architecture has changed for TFS 2010.  Your best bet is to read Brian Harry’s blog post on that topic and to focus on the section about Team Project Collections.  If you have used the TFS 2010 Beta 1 or Beta 2 APIs then it will be useful to read Grant Holliday’s blog post on the API renaming that we did.

Disclaimer: These classes were introduced in the RC version of TFS 2010. If you are using one of the Beta versions of TFS 2010 you will not see these classes.

In order to use the code from the examples in this post you will need the following include statements:

 using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Common;

The TfsConnection Class

The TfsConnection class is the abstract base class for the TfsConfigurationServer and TfsTeamProjectCollection objects.  Before we talk about when you should use each derived class let’s discuss the shared functionality that exists in their base class.  Just like the TeamFoundationServer class in the TFS 2008 OM, the TfsConnection object aims to provide you various information about your connection with TFS as well as ways to initiate and control that connection.  If it isn’t explicitly mentioned here, the functions and properties that existed on the TeamFoundationServer object will likely exist in the same way on the TfsConnection object.

Identity Management

By integrating with the new IIdentityManagementService, the TfsConnection object is able to give you a much richer experience around dealing with the identities that are involved in the connection with TFS.  On the old TeamFoundationServer object you probably remember the three properties that reported the user you were connected as, they were:

 public string AuthenticatedUserDisplayName { get; }
public Identity AuthenticatedUserIdentity { get; }
public string AuthenticatedUserName { get; }

Off of the new TfsConnection object you will find that this information along with other information is now available from this property:

 public TeamFoundationIdentity AuthorizedIdentity { get; }

You may also notice that the prefix of the property has changed from “Authenticated” to “Authorized”.  This has to do with the new TFS Impersonation feature that is usable with all TfsConnection objects.  Check out the blog post in the link for more information.  Once you have done that then hopefully you will find the new constructor overloads and this function more useful:

 public void GetAuthenticatedIdentity(out TeamFoundationIdentity identity);

Authentication

With the TeamFoundationServer object, getting the above user information always resulted in two server calls: one to actually authenticate with the server and the second to look information about the user you were connecting as.  In some cases, a third call was then made to read down location information so that other services (such as version control) could be used.  Fortunately, with the TfsConnection object, all of that information is now retrievable in a single call to the server via this method:

 public void Connect(ConnectOptions connectOptions);

Catalog Integration

If you are new to TFS 2010 then the catalog service is likely new to you as well.  Check out this blog post to learn some more about the catalog service.  The TfsConnection object integrates with the catalog service to easily make its CatalogNode object available to the consumer via this property:

 public abstract CatalogNode CatalogNode { get; }

This property will have different meaning based on whether the derived class is a TfsConfigurationServer or a TfsTeamProjectCollection object.  In the case where it is a TfsConfigurationServer object, the catalog node returned will be the one that represents the TFS instance.  In the case where it is a TfsTeamProjectCollection object, the catalog node returned will be the one that represents the given team project collection.

The TfsConfigurationServer Class

As you read in Brian’s blog post, in TFS 2010 we have introduced a new level of granularity between a TFS instance and the team projects that it contains.  That new level of granularity is called a team project collection and it is used to encapsulate a collection of team projects within a TFS instance.  The container for the set of team project collections is known as the configuration server.  In order to communicate with the configuration server you would construct a TfsConfigurationServer object using either its factory:

 TfsConfigurationServer configurationServer = 
    TfsConfigurationServerFactory.GetConfigurationServer(new Uri("https://server:8080/tfs"));

or one of its constructors:

 TfsConfigurationServer configurationServer = new TfsConfigurationServer(new Uri("https://server:8080/tfs"));

Of course, using the constructor will always create a new instance of the class while the factory will always give out the same instance of the class.  With this object you can now perform many actions against the configuration server.  Here is a (not necessarily exhaustive) list of services that you can get via the GetService<T>() call along with the tasks that they enable:

  • Microsoft.TeamFoundation.Framework.Client.ITeamFoundationRegistry: Exposes APIs for viewing and managing the contents of the TFS registry at the configuration server level.
  • Microsoft.TeamFoundation.Framework.Client.IIdentityManagementService: Exposes APIs for viewing and managing identities that exist in TFS and their group membership details at the configuration server level.
  • Microsoft.TeamFoundation.Framework.Client.ITeamFoundationJobService: Exposes APIs for viewing and managing job definitions, job schedules and job run history at the configuration server level.
  • Microsoft.TeamFoundation.Framework.Client.IPropertyService: Exposes APIs for reading from and writing to the generic property store at the configuration server level.
  • Microsoft.TeamFoundation.Framework.Client.IEventService: Exposes APIs for viewing and managing event subscriptions at the configuration server level.
  • Microsoft.TeamFoundation.Framework.Client.ISecurityService: Exposes APIs for viewing and managing security namespaces and the security data that each of those namespaces contain at the configuration server level.
  • Microsoft.TeamFoundation.Framework.Client.ILocationService: Exposes APIs for viewing and managing the services defined at the configuration service level along with their configured locations.
  • Microsoft.TeamFoundation.Client.TswaClientHyperlinkService: Exposes APIs for constructing URLs that communicate with TSWA.
  • Microsoft.TeamFoundation.Framework.Client.ITeamProjectCollectionService: Exposes APIs that allow you to perform management and servicing tasks on the set of team project collections.
  • Microsoft.TeamFoundation.Framework.Client.IAdministrationService: Exposes APIs for querying and canceling the active requests on the server.
  • Microsoft.TeamFoundation.Framework.Client.ICatalogService: Exposes APIs for viewing and managing the contents of the catalog.
  • Microsoft.TeamFoundation.Lab.Client.LabFrameworkService: Exposes APIs that allow you to perform verification of Lab Management objects during configuration.

One other thing you may want to do from your configuration server object is communicate with each of the team project collections that are members of this configuration server.  As we will discuss in the next section, all communication with a team project collection starts with the TfsTeamProjectCollection class.  In order to get the TfsTeamProjectCollection instance for a given team project collection you can call the following helper method from the TfsConfigurationServer class:

 public TfsTeamProjectCollection GetTeamProjectCollection(Guid collectionId);

One way you could possibly use this method is to enumerate the team project collections that you can see using the catalog to get each of their IDs and then use this function to construct the proxy for talking to that team project collection.  Here is an example of how that would be done. (Note, if you want a better understand of how the catalog is being used here, check out my blog post on enumerating the team project collections using the catalog).

 Uri configurationServerUri = new Uri("https://server:8080/tfs");
TfsConfigurationServer configurationServer =
        TfsConfigurationServerFactory.GetConfigurationServer(configurationServerUri);

CatalogNode configurationServerNode = configurationServer.CatalogNode;

// Query the children of the configuration server node for all of the team project collection nodes
ReadOnlyCollection<CatalogNode> tpcNodes = configurationServerNode.QueryChildren(
        new Guid[] { CatalogResourceTypes.ProjectCollection }, 
        false,                                                 
        CatalogQueryOptions.None);

foreach (CatalogNode tpcNode in tpcNodes)
{
    Guid tpcId = new Guid(tpcNode.Resource.Properties["InstanceId"]);
    TfsTeamProjectCollection tpc = configurationServer.GetTeamProjectCollection(tpcId);

    // Do your tpc work here.
}

So, now that you know how to get a TfsTeamProjectCollection class, let’s discuss that further.

The TfsTeamProjectCollection Class

From reading the topic above, you already know that you can get an instance of a TfsTeamProjectCollection class from its related TfsConfigurationServer object.  Of course, you can also create an object using the factory method:

 TfsTeamProjectCollection tpc = 
    TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("https://server:8080/tfs/Collection"));

or from one of its constructors:

 TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri("https://server:8080/tfs/Collection"));

Out of the three classes presented in this blog post, this class is the most like the old TeamFoundationServer object because of the services you can get from it.  Just like the old TeamFoundationServer object, this class provides the capability for talking to the version control, work item tracking and build services as well as all of the other services that you used in the TFS 2005 and 2008 to work with your team projects.  Because of this, you can use the TfsTeamProjectCollection class to talk to TFS 2010 team project collections as well as 2008 and 2005 instances of Team Foundation Server.

Speaking of the services that you can get from the TfsTeamProjectCollection.GetService<>() method, let’s take a look at another (not necessarily exhaustive) list of services that TFS ships with:

  • Microsoft.TeamFoundation.Framework.Client.ITeamFoundationRegistry: Exposes APIs for viewing and managing the contents of the TFS registry for this team project collection.
  • Microsoft.TeamFoundation.Framework.Client.IIdentityManagementService: Exposes APIs for viewing and managing identities that exist in TFS and their group membership details for this team project collection.
  • Microsoft.TeamFoundation.Framework.Client.ITeamFoundationJobService: Exposes APIs for viewing and managing job definitions, job schedules and job run history for this team project collection.
  • Microsoft.TeamFoundation.Framework.Client.IPropertyService: Exposes APIs for reading from and writing to the generic property store within this team project collection.
  • Microsoft.TeamFoundation.Framework.Client.IEventService: Exposes APIs for viewing and managing event subscriptions for this team project collection.
  • Microsoft.TeamFoundation.Framework.Client.ISecurityService: Exposes APIs for viewing and managing security namespaces and the security data that each of those namespaces contain for this team project collection.
  • Microsoft.TeamFoundation.Framework.Client.ILocationService: Exposes APIs for viewing and managing the services defined for this team project collection along with their configured locations.
  • Microsoft.TeamFoundation.Client.TswaClientHyperlinkService: Exposes APIs for constructing URLs that communicate with TSWA.
  • Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer: Exposes APIs for performing all version control related operations.
  • Microsoft.TeamFoundation.Build.Client.IBuildServer: Exposes APIs for viewing and managing build controllers, build agents, build definitions, build results and the build queue.
  • Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore: Exposes APIs for performing all work item tracking related operations.
  • Microsoft.TeamFoundation.TestManagement.Client.ITestManagementService: Exposes APIs for viewing and managing test controllers, test runs and test results.
  • Microsoft.TeamFoundation.Lab.Client.LabFrameworkService: Exposes APIs that allow you to perform verification of Lab Management objects during configuration.
  • Microsoft.TeamFoundation.Lab.Client.LabAdminService: Exposes APIs for viewing and managing the top-level lab management objects.
  • Microsoft.TeamFoundation.Lab.Client.LabService: Exposes APIs for viewing and managing other lab management objects.
  • Microsoft.TeamFoundation.Lab.WorkflowIntegration.Client.IWorkflowIntegrationService: Exposes APIs for viewing and managing workflow integration for lab environments that are created by the Team Foundation Lab Service.
  • Microsoft.TeamFoundation.Lab.TestIntegration.Client.ITestIntegrationService: Exposes APIs for viewing and managing the testing capability with lab environments that are created by the Team Foundation Lab Service.
  • Microsoft.TeamFoundation.ILinking: Exposes APIs for the retrieving the details about linking artifacts and their URLs.
  • Microsoft.TeamFoundation.Server.ICommonStructureService3: Exposes APIs for viewing and managing areas, iterations, and team projects.
  • Microsoft.TeamFoundation.Server.IServerStatus: Exposes APIs for getting the status of the server.
  • Microsoft.TeamFoundation.Server.IProcessTemplates: Exposes APIs for viewing and managing the process templates for this team project collection.

There are also some services that can still be retrieved using GetService<T>() because of backwards compatibility reasons but have replaced by newer services.  Here are a list of those with the service(s) they have been replaced by.

  • Microsoft.TeamFoundation.Server.IRegistration: This has been replaced by the ILocationService and ITeamFoundationRegistry services from above.
  • Microsoft.TeamFoundation.Server.ICommonStructureService: This has been replaced by the ICommonStructureService3 service from above.
  • Microsoft.TeamFoundation.Server.IGroupSecurityService: This has been replaced by the IIdentityManagementService from above.
  • Microsoft.TeamFoundation.Server.IGroupSecurityService2: This has been replaced by the IIdentityManagementService from above.
  • Microsoft.TeamFoundation.Server.IAuthorizationService: This has been replaced by the ISecurityService from above.

Also, just as the TfsConfigurationServer class has a helper method for retrieving TfsTeamProjectCollection objects, the TfsTeamProjectCollection class has a property for retrieving the TfsConfigurationServer object that it is a member of:

 public TfsConfigurationServer ConfigurationServer { get; }

I notice that some services can be retrieved from both TfsConfigurationServer and TfsTeamProjectCollection instances. Why is this and how are they different?

Great observation.  The services that are available from both of these objects are known as “framework” services.  From the list above you can see that the ITeamFoundationRegistry, IIdentityManagementService, ITeamFoundationJobService, IPropertyService, IEventService, ISecurityService and ILocationService are all framework services.  Whether you get these services from a TfsConfigurationServer or TfsTeamProjectCollection object, they will still provide the same functionality but the scope that you are affecting with those methods will be different.

Let’s look at the ISecurityService to demonstrate this.  One of the functions this service provides is the ability to list all of the security namespaces that exist for that host.  If you list the security namespaces for a security service that was retrieved from a TfsTeamProjectCollection object then you will see a security namespace for version control because we apply security to version controlled items within a team project collection.  However, you would not see this security namespace exist for a security service retrieved from a TfsConfigurationServer object because version control does not exist within the configuration server.  The opposite is true for the team project collection management security namespace.  This namespace will only exist for a security service retrieved from a TfsConfigurationServer object because it offers functionality for managing team project collections.

The same is true for all of the other framework services.  If you set a registry entry using the ITeamFoundationRegistry service from a TfsTeamProjectCollection object, it will not have any affect on the ITeamFoundationRegistry service from the TfsConfigurationServer object.  The same is also true for TfsTeamProjectCollection objects that talk to two different team project collections.  Setting a security or registry entry against on team project collection will not affect the security or registry setting in a different team project collection object.

Hopefully this gives you a good jumping off point for utilizing these new classes.  Feel free to hit up the comment section below or the contact link above if you have any questions.