I recently blogged about my love-hate relationship with VSX (Visual Studio eXtensibility). On the one hand, Visual Studio 2008 provides a developer experience second-to-none, has stellar support for customization and is the most flexible IDE I've ever seen. On the other hand, writing packages (basically a fancy word for Visual Studio customizations) using the Visual Studio 2008 SDK is akin to eating the quadruple bypass burger at the Heart Attack Grill: It looks fantastic on paper but actually doing it will likely be hazardous to your health.
I don't know why some product teams at Microsoft (Office, Visual Studio) have held on so dearly to their COM and OLE roots, but they have. I'm sure there's a good reason -- the type of good reason that would take too long to explain in this blog post, so let's leave it at they've got their reasons. Even though the Visual Studio 2008 SDK provides .Net Managed classes for almost all VSX operations, they're little more than 1:1 wrappers for their COM counterparts. Enter VSXtra.
VSXtra is what the .Net Managed classes in the VS2008 SDK should have been. Basically, it's a declarative approach to Package design, which allows the developer to leverage familiar .Net constructs (Attributes, generic types, IEnumerable, etc.) to build Visual Studio 2008 customizations. The project is still in alpha (on CodePlex), but the Microsoft MVP (affectionately known only on his blog as DiveDeeper) authoring the project is off to a fantastic start. The better news? To date, the blogger has put together 33 presentations on how to leverage VSXtra to build your own Visual Studio customizations.
Let's take a simple example. Say you want to enumerate through the Visual Studio 2008 task list (although that video sample does much more). It's absolutely fantastic that such a capability exists. Using the VS 2008 SDK without VSXtra, here's a small snippet of code that actually does this abomination.
private List<IVsTaskItem> GetCurrentTasklistTasks()
{
List<IVsTaskItem> tasks = new List<IVsTaskItem>();
IVsTaskList taskList = (IVsTaskList)GetService(typeof(SVsTaskList));
IVsEnumTaskItems enumTaskItems;
taskList.EnumTaskItems(out enumTaskItems);
int result;
uint[] fetched = new uint[1];
do
{
IVsTaskItem[] taskItems = new IVsTaskItem[1];
result = enumTaskItems.Next(1, taskItems, fetched);
if (fetched[0] == 1)
{
IVsTaskItem taskItem = taskItems[0] as IVsTaskItem;
tasks.Add(taskItem);
}
}
while (result == VSConstants.S_OK && fetched[0] == 1);
return tasks;
}
Got a headache yet? I know I do. What's up with the need to manually create and consume an enumerator? Wouldn't it be much easier to just have a static method (e.g. GetTasks) that could return a generic list of tasks? Why does such a thing not exist in the VS 2008 SDK? There's a countless number of examples just like this littered through the SDK's documentation.
Thanks, DiveDeeper, from the bottom of my heart, for taking the time to create a managed library that the rest of us can actually use. I look forward to seeing this library progress into a 1.0.
bc320661-5686-4427-b195-1823c0c607f4|0|.0
Development
visual studio 2008