Thursday, November 11, 2010

Why the Enterprise Search Web Parts are sealed

I can’t claim to know the real political reasons behind this, which according to Corey Roth’s blog post last December is because “it’s by design”. In my mind “by design” is not a real reason.
For non .Net programmers, a sealed web part means that you cannot inherit from it, doing your own customizations.
So, why are they really sealed?

After investigating the code of the web parts with Reflector (more on that later) I have found that a lot of functionality is hard coded towards either the internal SharePoint Search location or the FAST search location. And if compilation hasn't played a trick on the length of the functions in these web parts, they are way too long for my liking, often 70+ lines. By depending so closely on the underlying search components they are in many cases useless to inherit from anyways. The parts you would override would need to contain so much logic and code that you might be better off writing your own web part from scratch. Sealing them at least prevents your from inheriting from something which is hard to work with.
In my mind an OOB (out-of-box) web part should be flexible in terms of configuration, and small changes in code if you inherit from it. A common scenario wanted by many is extending the search web parts is to add an asterisk ‘*’ to a search term, executing it as a wildcard. This is possible today with the CoreResultsWebPart, but not with the PeopleCoreResultsWebPart, which actually inherits the CoreResultsWebPart. And if you want to extend it further to support FQL (FAST Query Language), then you are out of luck, because you have to use the KeywordQuery class for that, which is not accessible thru the web part itself.
Let’s look a bit closer at some of the OOB web parts.
CoreResultsWebPart Unsealed Displays the results for a search query in the SharePoint Enterprise Search UI.
PeopleCoreResultsWebPart Sealed Displays the results for a people search query in the Enterprise Search UI, inherited from CoreResultsWebPart.
SearchStatsWebPart Sealed Displays the search query's statistics in the Enterprise Search UI. “1-10 of 50 results”
SearchSummaryWebPart Sealed Displays the summary for a search query in the Enterprise Search UI. “Did you mean” functionality.
Using Reflector (a tool to decompile .Net assemblies) to find out what happens behind the scenes I have reviewed the actual code in these web parts and the main discovery is that a lot of functions include lines looking something like this:
if (Config.Type == LocationType.FASTSearch)
if (Config.Type != LocationType.FASTSearch)
if (Config.Type == LocationType.LocalSharepoint)
if (Config.Type != LocationType.LocalSharepoint)

What this means is that if the data comes from the built-in SharePoint Search or from FAST, then the web part will have certain logic. If the data comes from say an Open Search provider, or a custom provider you have created against a line of business application, then something else happens.

To illustrate the point you can compare the two images below. The first is a search executed against the FAST location, and the second is executed against a custom location, which again calls the FAST location. So both have the same data at hand.

FAST

fastlocation

Custom

customlocation


They both look about the same but with a couple of differences.

In the SearchStatsWebPart it will not render “of 1234 results” unless you use one of the two built-in providers. Even though you might actually have the information and you set it in your code.

In the CoreResultsWebpart, Action Links are not displayed unless you use one of the two built-in providers, meaning you cannot do RSS feeds or alerts against a custom search location, even though it works just fine. Also if you want to show preview thumbnail of Word and PowerPoint you have to execute the query directly against the FAST location if you are using the default XSLT.

Modifying the PeopleSearchCoreResultsWebPart is interesting if you want to add wildcard to the searches, but not possible today. You have to roll your own search web part instead, and pick out the guid's for the different rank profiles. So instead of configuration, you are forced into development.

SearchSummaryWebPart is much like the Stats Web Part. You can provide the data all you want, but if you want it rendered with this OOB web part you have to execute the search against FAST or the built-in search.

What it all boils down to is this:

If you want to use the OOB web parts, you should also use the OOB search capabilities. Any deviation will force you to write code.

I suspect time ran out for SharePoint 2010, and we can hope for better and more flexible web parts in the next release. Until then we have to rely on our programming skills and roll our own, using time on plumbing development instead of creating great solutions.

This post is cross-posted at Comperio Nuggets.