I have some answers! Feel free to contribute your own findings.
As far as I know, there are 3 main ways to retrieve a simple list of Team Projects from TFS:
- Using the new Catalog service (TFS 2010)
- Using the VersionControlServer (TFS 2008/2010)
- Using the ICommonStructureService (TFS 2008/2010)
The simple tests I conducted compared the three methods when counting the total number of projects returned.
Method 1: Catalog Service (TFS 2010 Only)
public IEnumerable<string> GetTeamProjectNamesUsingCatalog()
{
ReadOnlyCollection<CatalogNode> projectNodes = new TfsTeamProjectCollection(collectionUri).CatalogNode.QueryChildren(
new[] { CatalogResourceTypes.TeamProject },
false, CatalogQueryOptions.None);
foreach (var tp in projectNodes)
yield return tp.Resource.DisplayName;
}
Method 2: VersionControlServer
public IEnumerable<string> GetTeamProjectNamesUsingVCS()
{
TfsTeamProjectCollection tp = new TfsTeamProjectCollection(collectionUri);
foreach (var p in tp.GetService<VersionControlServer>().GetAllTeamProjects(false))
yield return p.Name;
}
Method 3: ICommonStructureService
public IEnumerable<string> GetTeamProjectNamesUsingStructureService()
{
var structService = new TfsTeamProjectCollection(collectionUri).GetService<ICommonStructureService>();
foreach (var p in structService.ListAllProjects())
yield return p.Name;
}
The unit tests I ran were super simple. I used the .Count() method to make sure we iterated all the team projects (.Any() is faster as it will stop after the first name is returned).
Results
For TFS 2010, running 3 tests 5 times in a row:
For TFS 2008, running 2 tests (no Catalog service) 5 times in a row:
Biases
- The TFS 2010 server this was running against was in development, so hardly anyone was using it.
- I didn't test this with any least-privilege user accounts; I am an Admin on the server.
- I am communicating with a TFS server within the corporate network.
- In TFS 2010, you can have multiple
TfsTeamProjectCollections
; you will need to iterate through those as well. In this test, I only used one collection. - I used the constructor for creating the
TfsTeamProjectCollection
; I switched to using theTfsTeamProjectCollectionFactory.GetTeamProjectCollection()
method and it was actually slower each test run. It might be faster if you make multiple calls per request. - For TFS 2008, the server is a production server under load (i.e. real world).
Findings
As you can see, it seems like the ICommonStructureService
is fairly fast at finding all the team projects after the first execution. Note: I had done earlier tests using ICommonStructureService3
(new in TFS 2010 API) and the same code was slower than the other two methods.
If consistent performance is key, I think I'd recommend VersionControlServer
to do it.
Keep in mind what it is you want to do with the team projects, however. If simply listing them is all you need, the ICSS is probably the way to go. If you want to use the list for navigation, you'll also need the path ($/TeamProject
) or Uri. In that case, VCS is probably the best way to go as you can use the ServerItem
property, which holds the path to the item. You might also get away with simple string concatenation using ICSS ("$/" + p.Name
).
Hope this helps some other TFS API developers.