Feature Chaining: Activation Dependencies and Feature Stapling
I recently created a series of SharePoint features that when activated would produce a highly customized SharePoint site. These features are highly dependant on each other so they must be activated in order or there might be problems. I also wanted to make provisioning of the sites as easy as possible for end users so that they would not have to manually activate these custom features. To accomplish this I decided to go the route of a feature/site template association or more commonly, feature staple. Feature stapling allows you to associate a feature with a site definition so that when a site based on a specified site template is provisioned, the associated feature(s) are activated as well. If you are not familiar with feature stapling you can find more information at http://delicious.com/tag/feature%20stapling.
The features that I wanted activated all built upon each other. In this case, I had a security feature that modified lists provisioned in another feature that was based upon custom list template that used a content type provisioned in another feature (see illustration below).
Another challenge was the scope of the features. The Site Security and List Provisioning features were both Web scoped features while the Custom List Template and Custom Field and Content Type features were scoped at the Site level.
Test 1: Staple Each Feature
The first thing that I tried was to staple each feature. In my stapling feature, I referenced each of the four features in the element manifest using four <FeatureSiteTemplateAssociation/> elements. In the manifest, I listed these in the order in which I wanted them to be activated. What I found was that the features could be activated in any order. This obviously caused problems for me since each feature relied on items provisioned by another feature.
* This may work well when you have a bunch of features to activate that do not have any dependencies between them.
Test 2: Activation Dependencies and Hidden Features
The next thing that I tried was doomed from the start. I wanted my features hidden so that users would not be tempted to turn them on or off. To try to correct the problem from my previous attempt, I added <ActivationDependency/> tags to my feature.xml files so that each feature was dependant on the previous one in the chain.
Now, I received errors when trying to active features like: Dependency feature with id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx for feature ‘XXXXXXXXXXXXXX’ (id: xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) is not installed.
And when I tried to install the dependant feature I got the error: Hidden features with activation dependencies are not supported.
The SDK page ActivationDependencies Element (Feature) states that only hidden features can be activated/deactivated automatically and that hidden features can not have activation dependencies. This means that you must have a visible feature to activate and that you can only activate features from the visible feature. You can not have a hierarchy of hidden features dependant on each other and have them all automatically activate in the correct order. I would love it if you could do this though.
Test 3: Visible Feature with Activation Dependencies (mixed scopes)
Realizing that I was only going to be able to automatically activate features one level deep. I created a new Web scoped feature that was visible and added each of my other features as activation dependencies again, listing them in the order in which I wanted them activated. I then changed my stapling feature to staple only this new feature. All of my other features are now hidden and without any activation dependencies. I thought for sure this would work, again I was wrong.
Again I received the error: Dependency feature with id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx for feature ‘XXXXXXXXXXXXXX’ (id: xxxxxxxx-xxxx-xxxx-xxxx-xxxx-
xxxxxxxxxxxx) is not installed.
What I noticed here was that both of my Web scoped features were activated, but neither of the Site scoped features were. For some reason – I don’t know why – I was surprised to find that a Web scoped feature could not automatically activate a Site scoped feature.
Test 4: Visible Feature with Activation Dependencies (single scope)
Even though that I felt that my two Web scoped features were not appropriate to be scoped as Site I decided to try it anyway. Sure enough everything worked – after some adjustments to my feature receivers. Just out of curiosity, I created some dummy features that were all scoped at the web level and it worked as well.
This brings us to a rule of automatic feature activation:
A visible Web scoped feature can only auto-activate hidden Web scoped features and a visible Site scoped feature can only auto-activate hidden Site scoped features.
If you want to automatically activate features when a site is provisioned use feature stapling when feature dependency does not matter or if all of your features are scoped at the same level. If things are really complex and you have features at different scopes that depend on each other a custom site definition may work better.
Here is a list of some general guidelines for when to use the different options for feature activation:
- Features that do not depend on each other.
- Activation of a feature with hidden activation dependencies.
Saved Site Template
- Features and customizations done in the browser and provisioning code does not need to be run.
Feature with Hidden Activation Dependencies
- Single click activation of multiple features at the same scope.
- Complex feature chaining.
- A small database storage footprint is necessary.
- When you want to activate features to a specific site type.