Regarding the IDTExtensibility2 interface

I have always wondered why the IDTExtensibility2 interface of the Visual Studio host to load (or connect) add-ins is not as simple as just two methods: OnLoad and OnUnload, or if you like the “connection” term, just the OnConnection and OnDisconnection methods. The original IDTExtensibility interface of Visual Basic 5/6 from 1997/1998, which offered four methods (OnConnection, OnDisconnection, OnAddInsUpdate and OnStartupComplete), rather than being simplified in the transition to VS.NET 2002, got a new life as IDTExtensibility2, with even a new method (OnBeginShutdown).  All of them seem totally unnecessary to me, let see why:

  • OnAddInsUpdate: this is perhaps the most useless method. I have yet to see an add-in that makes some use to it. Anyone? It’s good that you can access other add-ins from yours using the DTE.AddIns collection, and even that you can unload some add-in using the AddIn.Connected property (long time ago my MZ-Tools add-in had to unload a conflicting add-in before an operation to avoid a crash and reload it afterwards), but there is no much need to get notified when an add-in is loaded/unloaded. If there is, some event in the DTEEvents class would be better than a method of an interface that you have to empty-implement.
  • OnStartupComplete: this method is called when the add-in is loaded on startup and the IDE is fully initialized (because when the OnConnection method was called, it was not fully initialized). I have yet to see an add-in that needs to behave differently when it is loaded on startup, or sometime later through the Add-in Manager, or that wants to do something before the IDE is not fully initialized. The MSDN documentation states:

    “On occasion, OnConnection does not occur correctly, such as when an add-in is loaded, but a component required by an add-in has not yet loaded. This is unusually due to the fact that Visual Studio has not yet started completely.”.

    In such case I would prefer my OnConnection method to be called when the IDE is fully loaded, not before that. The behavior of OnConnection / OnStartupComplete is so confusing that I had to write an article to show how to do it right, tired of seeing wrong code in the forums.

  • OnBeginShutdown: this is another useless method. The MSDN documentation states:

    “Although a shutdown of Visual Studio might be canceled, the OnBeginShutdown method cannot be canceled. As a result, add-ins should assume that all shutdown events occur and perform any cleanup routines accordingly.”.

    So, when Visual Studio thinks it is going to shutdown, it calls this method and your add-in has to cleanup. What is going to do then when it receives the OnDisconnection call?. But wait! The shutdown could be cancelled (for example, if there are dirty documents, the user is prompted to save them and she cancels), but, alas, your add-in already did the cleanup…  I don’t see the point. Either this method is useless, or at the very least it should be called when the IDE is totally sure that it is going to shutdown (after giving the user the last chance to cancel, to begin with).

BTW, the ext_ConnectMode.ext_cm_UISetup flag of the OnConnection method is so special, the add-in is loaded (or connected) for such a special purpose (to create the commands and permanent user interface of the add-in) that it truly would deserve its own OnUISetup method.

So, if correct initialization/shutdown of add-ins is so tricky, it is no wonder that developers entering the Visual Studio automation world find it so hard.

FWIW, Microsoft recognized this need of simplification in the new managed add-in models for Microsoft Office using Visual Studio Tools for Office (VSTO) 2005 (see the Startup/Shutdown events in VSTO 2005), or in the new IManagedAddIn interface of Office 2007 with its Load/Unload methods. I am not familiar with those models but seeing the docs you realize that you have to deal with just one event on load and just one event on unload. A good step in the right direction.