The most common task when deploying your solution is to activate custom and out of the box features. In the first chapter of my book – we looked at how you can automate the process using PowerShell saving yourself from manual deployment of your solution. However, PowerShell snap in for SharePoint doesn’t have a method to activate features with properties. There are quite a few of out of the box features with properties, let alone your might have few of your own if you want to pass parameters to your features.
Recently I found very good reference over here on how you can use .NET reflection and pass activation properties to your features. In this article I would like to provide simplified example that you can compile quickly and possibly latest show you how same can be done in PowerShell.
First, we’re going to create a new SharePoint solution which will provision just one feature with receiver.
1. In your Vsiaul Studio Blank SharePoint project add a feature
2. Add a receiver to the feature
3. Add the following code to the receiver’s FeatureActivated method:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWeb web = properties.Feature.Parent as SPWeb;
if (properties.Feature.Properties["Test"]!=null)
{
web.Title = properties.Feature.Properties["Test"].Value;
web.Update();
}
}
Basically a new feature parameter called “Test” is being accepted and the value of that parameter will be set as a title of the web. Deploy the solution – you will notice the feature will be installed in your site but not activated.
Let’s see how we can activate the feature with parameters using a custom webpart
1. Create a new SharePoint project in Visual Studio of type Visual Webpart
2. In the code behind of of the user control add the following code to the Page_Load method:
protected void Page_Load(object sender, EventArgs e)
{
SPWeb web = SPContext.Current.Web;
web.AllowUnsafeUpdates = true;
Dictionary<string,string> activationProps = new Dictionary<string,string>();
activationProps.Add("Test", "This is my title");
web.Features.ActivateFeature(new Guid("1a3fea9d-251d-42ce-a72e-5f138629c0c1"),
activationProps);
web.Update();
}
Above, the GUID is simply the ID of the feature we created before. In this part we’re passing a parameter to our extension method called ActivateFeature with the properties and the ID of the feature. Let’s now implement the extension method provided by Hristo in the above article:
The extension class (with 2 methods) will go into the separate class and will be referenced by the user control, here is the code of the class:
public static class ExtensionForFeature
{
public static SPFeature ActivateFeature(this
SPFeatureCollection features,
Guid featureId,
Dictionary<string,string> activationProps)
{
ConstructorInfo propCollConstr =
typeof(SPFeaturePropertyCollection).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0];
SPFeaturePropertyCollection properties = (SPFeaturePropertyCollection)
propCollConstr.Invoke(new object[] { null });
foreach (string key in activationProps.Keys)
properties.Add(new SPFeatureProperty(key, activationProps[key]));
return ActivateFeature(features, featureId, properties);
}
private static SPFeature ActivateFeature(this
SPFeatureCollection features,
Guid featureId,
SPFeaturePropertyCollection properties)
{
MethodInfo getFeatureInternal =
typeof(SPFeatureCollection).GetMethod(
"GetFeature",
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new Type[] { typeof(Guid) },
null);
SPFeature alreadyActivatedFeature = (SPFeature)getFeatureInternal.Invoke
(features, new object[] { featureId });
if (alreadyActivatedFeature != null)
// The feature is already activated. No action required
return null;
MethodInfo addInternal =
typeof(SPFeatureCollection).GetMethod(
"Add",
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new Type[] { typeof(Guid), typeof(SPFeaturePropertyCollection), typeof(bool) },
null);
object result = addInternal.Invoke(features, new object[] { featureId,
properties, false });
return result as SPFeature;
}
}
Add the following namespace references:
using System.Reflection;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Linq;
using System.Linq;
The above extension class will use Reflection to access internal methods available in SharePoint and invoke those to pass parameters into your feature during activation.
Now, deploy your solution and add a new webpart to the page – during its activation you will see the second feature being activated and title of the web changed according to the feature parameter passed..
Enjoy!


