I've recently been working on a SharePoint project which is being offered to clients as a product built on top of the SharePoint framework. While I can't describe in too much detail exactly what the product is, I figured it might be beneficial to discuss how we've built out certain aspects of the solution. At the very least, I can compile some notes of my own so I can remember later how tackled some of the issues we had during the dev process.
To give a little background on the product, at the core, this is primarily a publishing-based solution that is deployed into a site collection. One of the goals in the development of the product has been to automate the creation of the site collection as much as possible when a new client purchases the product. We're handling the bulk of the new client deployment through a Feature called 'Product.SiteConfiguration' that when activated, executes a Feature Receiver that both creates some higher-level components and populates 'default' data in areas of the site that are required for the product to function properly.
One of the things we're creating in the SiteConfiguration Feature Receiver is a locally defined, custom search scope that is specific to the site collection of the product. A search scope allows the narrowing of search results based on rules defined within the scope, so we wanted to create a scope that is specific to the product so that when a user searches from the product's generic search box, only items from within the product are returned.
Here's sample code used to create a new scope in a site collection:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.Office.Server.Search.Administration;
using System.Diagnostics;
namespace LocalDev.Demo.Code
{
public class SiteConfiguration : SPFeatureReceiver
{
SPSite currentSite = null;
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
string scopeName = "ProductScope";
this.currentSite = properties.Feature.Parent as SPSite;
//get the site SSP's search server instance
SearchContext searchContext = SearchContext.GetContext(this.currentSite);
//get the current scopes defined in the search server
Scopes scopes = new Scopes(searchContext);
//create a URI object for the current site - used in checking for the scope we're creating
string siteUrl = this.currentSite.Url;
Uri siteUri = new Uri(siteUrl);
//create scope object for the new scope
Scope newScope = null;
try
{
//this is a little bit of a hack, but if it bombs, we know the scope doesn't exist
newScope = scopes.GetScope(siteUri, scopeName);
}
catch
{
//create the new scope
newScope = scopes.AllScopes.Create(scopeName, scopeName + " Description", siteUri, true, "/_layouts/product/customsearchresults.aspx", ScopeCompilationType.AlwaysCompile);
//create the scopes rules for the new scope
//for example, include content from the site
newScope.Rules.CreateUrlRule(ScopeRuleFilterBehavior.Include, UrlScopeRuleType.Folder, siteUrl);
//save the changes to the SSP Content Database
scopes.Update();
//start compilation of the scope
scopes.StartCompilation();
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}
}
}