Skip to main content

VS Extensibility - It's So Easy!

(Note: This is an old post that was stuck in my backlog. I am publishing it now with the intent of writing more VS extensibility posts.)

I have a colleague who laments the desire of developers to have (and tool developers to put) ‘everything in the IDE’. Anyone who has struggled with integrated source control fussing up a solution structure can probably identify with this view to some degree. Still, anyone who has used the NUnit GUI test runner for lack of having ReSharper or TestDriven.NET has had a taste of the case for IDE integration. When building small custom tools to enhance developer productivity and make it easy to perform mechanical tasks, why not stick them in Visual Studio? It turns out, it’s pretty easy to do.

Consider a situation in which a developer has user accounts for each tenant of a multitenant application. These accounts get deactivated after a period of non-use, so they need to get reactivated in order for the developer to troubleshoot problems that manifest only for a specific tenant. The developer usually just runs a script that resets the account to active; it’s about as simple as a maintenance task could be for a dev. Still, wouldn’t it be nice to have an easy way to track down the script and execute it? And wouldn’t it be nice to make sure all the developers used a standard method of performing this reset to prevent possible anomalies? We can make a little Visual Studio tool window with a button to execute this script. The tool window can be easily located in the Visual Studio menus.

First, create a Visual Studio Integration Package project

This will bring up a wizard, which is pretty self-explanatory. In this example, we’re creating just a tool window:

From there, it’s just a matter of creating a user control to do our bidding. The control is automatically included in the integration package project and named ‘MyControl’ by default. Integration and interoperability with VS is achieved through a Microsoft.VisualStudio.Shell.Package class (named ‘{PackageName}Package’ by default) and a wrapper class (‘MyToolWindow’ by default) which inherits from Microsoft.VisualStudio.Shell.ToolWindow and exposes the control to the IDE through the Window property.

I’ll spare the boring details on the implementation of this example control. The code can be found here.

Part of what makes developing the tool window so easy is the debugging experience – running the project launches an experimental hive with our custom tool window installed! Just go to View > Other Windows and select the User Reactivation tool:

This example featured a hardcoded backend with no configuration options. In the future, I’ll explore how to outfit your extensibility projects with configuration.

Comments

Popular posts from this blog

Who I'm Is

I am a junior .NET developer currently working in Chicago, IL. I am starting this blog in order to enhance my knowledge of programming subject matter. Hopefully, someone else will be helped along the way. This first post will probably be edited soon...

Stubbing Static Methods with PostSharp

TypeMock uses the Profiler API to allow mocking, stubbing, etc. of classes used by code under test. It has the ability to handle sealed classes, static classes, non-virtual methods, and other troublesome-yet-oft-encountered scenarios in the world of unit testing. Other frameworks rely on proxies to intercept method calls, limiting them to be able to only fake virtual, abstract, and interface members. They also rely on dependecy injection to place the proxies as the concrete implementation of calls to the abstracted interface members. Anyone working with a legacy codebase is bound to run into static method calls (especially in the data access layer), dependencies on concrete types with non-virtual methods, and sealed class dependencies (HttpContext anyone?). The only way to unit test this without refactoring is with TypeMock. I've never used TypeMock, and I'm sure it's a great product, but it's not free. I decided to spike some code to see if I could solve the prob...

Strongly-Typed Property Constraints in Rhino Mocks

UPDATE: As I suspected, this functionality was right in front of my face – it’s called PredicateConstraint in Rhino Mocks. I also realize that I managed to completely ignore the existence of Predicate<T> in the framework, and write my own predicate delegate. Hey, I was on a roll. Rhino Mocks has a PropertyConstraint class that allows you to check the values on properties of objects passed into the method as part of the verification for that method being called. Unfortunately, the name of the property is specified as a string, which means the benefits of strong-typing that Rhino Mocks is normally so good at preserving are lost. Here’s an example (using Rhino Mocks 3.3 and .NET 2.0): [Test] public void Main_Form_Should_Show_Start_Panel_On_Load() { MockRepository mockRepository = new MockRepository(); IMainFormView mockView = mockRepository.DynamicMock<IMainFormView>(); IEventRaiser loadEventRaiser = GetEventRaiserFor(delegate { mockView.Load += null; });...