Wednesday, February 13, 2008

Team Foundation Server and VSIP tidbits

One basic question that immediately comes up when writing Visual Studio Integration Package (VSIP) that needs to make use Team Foundation Server extensiblity, is how to handle TFS extensibility objects. "How to" for writing add-ins is well described in now classic blog post by Ed Hintz; while most of it applies also to VSIP there are some missing pieces that I will try to address.

As a first step, one needs to get TFS extensibility objects; once the extensibility objects are available, there is no major difference between add-in (as described in Ed's article) development and VS package.

To obtain reference to TFS specific objects (such as VersionControlExt) one needs DTE2 instance; in VSIP one may use the following approach to retrieve global DTE:

// use package GetService method to get
// extensibility service
EnvDTE.IVsExtensibility extensibility = 
   GetService(typeof(EnvDTE.IVsExtensibility)) as EnvDTE.IVsExtensibility;
// get IDE Globals object and DTE from that
EnvDTE80.DTE2 dte2 = 
   extensibility.GetGlobalsObject(null).DTE as EnvDTE80.DTE2;
            Debug.Assert(dte2 != null, "No DTE2");

Once reference to DTE2 is available, reference to TFS extensibility objects may be obtained as follows:

VersionControlExt versionControlExt = 
   dte2.GetObject("Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt") 
   as VersionControlExt;

Another frequently asked question is how to monitor when TFS server connection status in Visual Studio IDE. There is no special event exposed for this purpose; however, ProjectContextChanged event of TeamFoundationServerExt object may be used for this purpose (see Tim Noonan's excellent post for more details on this event). When TFS server is disconnected, active project context properties become null; when connected, the values in the context can be used to get reference to TeamFoundationServer object:

private void ProjectContextChanged(object sender, EventArgs e)
{
    // server is disconnected
    if (_teamServerExt.ActiveProjectContext.DomainName == null)
        ; // do disconnected stuff
    else 
    {
        // connected, can get reference to server
        //TeamFoundationServerFactory.GetServer(
        //    _teamServerExt.ActiveProjectContext.DomainUri.ToString());                
    }
}

Tracking TFS server connection status may seem unimportant, but it becomes vital in scenarios with several TFS servers available, or where VS may be started disconnected with connection to TFS established later on. In such cases assuming that the connection is always active may lead to some ugly bugs in your package.

No comments: