I don’t normally pay a lot of attention to what SharePoint does when deactivating features, retracting solutions and deleting solutions; I’m usually much more interested in what happens as things are installed: did I get everything right in manifest.xml? Did all the files get deployed correctly? And so on.
Now I’m a bit of a neat freak and to date I’ve always been reasonably impressed with how SharePoint actually deletes the folder wrapping a feature when the solution is removed and generally cleans up after itself. I wasn’t so excited, however, when I realised SharePoint still leaves some junk behind—where it’s visible to users and clients in the Web Parts gallery, no less. If I request a feature be deactivated, I expect it to be deactivate in full, not leave web parts listed in the Web Parts gallery that when added to a page will simply break.
I was also noticing the modified date in the Web Parts gallery wasn’t updating as I redeployed and reactivated my solutions/features. I’m not clear on this but I wonder if that means the web part definition isn’t getting updated in the site collection (it was suggested elsewhere).
A quick search reveals this is normal SharePoint behaviour but luckily two guys have come up with an elegant solution to remove spurious web parts from the gallery when the containing feature is deactivated; the only downside is the feature must be explicitly deactivated—simply retracting the solution and even following up by deleting the solution from the solution store won’t trigger the feature receiver’s FeatureDeactivating method. Of course these web parts can be deleted manually but we all know that sucks.
Anyway, it’s a fine start: Greg Galipeau kicked off a first draft that removes a single web part based on the feature name and Trent Foley applied some nice LINQ wizardry to remove all the web parts listed in the feature’s element definitions. Nice work guys! My contribution? Well apart from saying thanks, I’ve tested out Trent’s implementation and proven it works brilliantly; I’ve also swapped out the var declarations for concrete types to assist with my understanding and because I like being explicit (I won’t bother posting the code unless someone requests it).
Next step: page layouts? ;-)