What’s maybe a bit odd at first is that the Microsoft.VisualStudio.Services.InteractiveClient NuGet package contains and references a ‘Microsoft.VisualStudio.Services.Client.dll‘ assembly, while the ‘Microsoft.VisualStudio.Services.Client‘ NuGet package, even though named like the aforementioned assembly, contains *.Common assemblies only (basically the core contracts).

So even though the name and description implies user interaction, the ‘Microsoft.VisualStudio.Services.InteractiveClient‘ contains the interesting and useful bits, even without actual user interaction.

This will pull in a couple dependencies the packages have and reference about a dozen Microsoft.TeamFoundation.* and Microsoft.VisualStudio.* assemblies.

Now in order to make your first connection and actually retrieve data from your TFS Server, you will need the following information:

URL of the target Team Project Collection

Identifier for the artifact that you want to retrieve, i.e. a work item id

And the entire code to retrieve the later (work item) by its .Id looks like this:

These 3 lines basically make a connection (and in this case authenticate implicitely via NTLM, more about authentication will come later), get ahold of a WorkItemTrackingHttpClient and use the later to retrieve the Work Item with .Id 1 and then prints out some of its info the console.

Moreover, some functionality may only work for the Microsoft hosted Visual Studio Team Services and not (yet) for on-premises Team Foundation Server installations as the release cycle of the later follows the former at a slower pace.

What’s also worth mentioning is that currently (v14.95.3 as of writing) the Types and Members exposed by the .Net Client library/libraries are somewhat inconsistently named (some have pre- and suffixes, some have abbreviations in their names, some do not) and their signatures appear to not follow a coherent guideline – some expose Task<List<T>>, some however return Task<IEnumerable<T>> (which seems a bit odd knowing that proper async enumerables aren’t there, yet), many methods do take an optional CancellationToken, many other methods don’t and it’s not clear why (the underlying base class(es) appear to boil down to helpers around standard HttpRequestMessage and HttpResponseMessage utilizing a normal HttpClient which works nicely with CancellationTokens.

As this may be confusing to some, I hope they’ll correct this somewhere down the road and provide a uniform and consistent library throughout and when they do, some of the sample code shown in this series of posts may no longer work as-is.