How to re-activate ActivationDependencies in SharePoint

As you may (or not may) know, activation dependencies are a great way to get a bit of automatic activation of features and to not get a whole bunch of features in the UI.
As long as you make your dependency features hidden they will get activated automatically as opposed to visible dependency features that will just generate an error message.

I usually use a “master” feature that´s connected to a custom sitedefinition that activates a couple of smaller “utility” features.

The only really annoying thing about activation dependencies is that they are only activated as long as the dependency feature is not already activated (…they don´t work on reactivation…or do they?).

An example

I have a “master” feature that I´m calling from onet. This feature is visible and acts as a master for all other “smaller” features. I have, in this example, only one activation dependency.


<Feature xmlns="<a href="http://schemas.microsoft.com/sharepoint/">http://schemas.microsoft.com/sharepoint/</a>"
         Hidden="FALSE"
         Id="E03C5E8B-5156-4915-AA12-BF60018E8976"
         Title="Contoso OrderApplication"
         Description="Contoso OrderApplication SiteDefinition Feature."
         ReceiverAssembly="Contoso.OrderApplication.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=75b5c1d749f0edcf"
         ReceiverClass="Contoso.OrderApplication.SharePoint.FeatureReceivers.OrderApplication"
         Scope="Site"
>
    <ActivationDependencies>
        <ActivationDependency FeatureId="b454e5b5-f27c-4b74-bf62-e88febfd8d68" />        
    </ActivationDependencies>
</Feature>

This is my activation dependency feature:

<Feature  Id="b454e5b5-f27c-4b74-bf62-e88febfd8d68"
          Title="Contoso.Common"
          Description="Common stuff used by the whole application"
          Hidden="TRUE"
          Scope="Site"
          DefaultResourceFile="core"
          ReceiverAssembly="Contoso.OrderApplication.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=75b5c1d749f0edcf"
          ReceiverClass="Contoso.OrderApplication.SharePoint.FeatureReceivers.Common"
&#91;/sourcecode&#93;

<a href="http://11011.net/software/vspaste"></a>

As you can see it´s <strong><em>hidden</em></strong> and that´s important because I want this feature to automatically be activated when someone activates the “master” feature. And on activation I simply provision a list and it shows up like this:

<a rel="WLPP" href="https://o8b6nw.bay.livefilestore.com/y1mPFS2F3hfFEiTGToXA5t4cJYRh0YGBh9ja1A3aWXUSdBMwwUVMfnFmIUGaqSg-ZGQNzJlkzzEY5GJEodtLu3R1dtCAQ79MVw_FNneEZvT-Rcl5Ow1a9k75EPDDeVMHxNnZulp0ehYtsMmnu4VB_l6TQ/image&#91;3&#93;%2059E5946C.png"><img style="display:inline;border-width:0;" title="image" src="https://o8b6nw.bay.livefilestore.com/y1mlEW-Dj3hOaLUuh-vzRywmkZjMTIZ5XaHOdk30LgDL9Ep2RwvlJ7T8s7-QN5KHySyDIJSXu48T1tCNRj0AtgMkkhe4PMwaWHPZSbnG_uFvrb27wZcMildOrH9KIpP-BHYy0_nfHHokEKwO-c46WGFGg/image_thumb&#91;1&#93;%2000272C1E.png" border="0" alt="image" width="160" height="59" /></a>

 I now make a minor change to my dependency feature code to make my point:
<pre>list.Title = <span style="color:#a31515;">"The common list"</span>;
list.Update();</pre>
<a href="http://11011.net/software/vspaste"></a>

…updating the title of the list.
…and when I deactivate/activate the “master” feature:

<a rel="WLPP" href="https://o8b6nw.bay.livefilestore.com/y1mPFS2F3hfFEiTGToXA5t4cJYRh0YGBh9ja1A3aWXUSdBMwwUVMfnFmIUGaqSg-ZGQNzJlkzzEY5GJEodtLu3R1dtCAQ79MVw_FNneEZvT-Rcl5Ow1a9k75EPDDeVMHxNnZulp0ehYtsMmnu4VB_l6TQ/image&#91;3&#93;%2059E5946C.png"><img style="display:inline;border-width:0;" title="image" src="https://o8b6nw.bay.livefilestore.com/y1mlEW-Dj3hOaLUuh-vzRywmkZjMTIZ5XaHOdk30LgDL9Ep2RwvlJ7T8s7-QN5KHySyDIJSXu48T1tCNRj0AtgMkkhe4PMwaWHPZSbnG_uFvrb27wZcMildOrH9KIpP-BHYy0_nfHHokEKwO-c46WGFGg/image_thumb&#91;1&#93;%2000272C1E.png" border="0" alt="image" width="160" height="59" /></a>

Nothing happens!
As expected, it doesn´t fire when I deactivate and activate (aka re-activate) the “master” feature. But I want that to happen, so I´ll try to go around that limitation in SharePoint.
<h2><strong>The Solution</strong></h2>
The idea is to run a piece of code in my “master” feature that deactivates all of the dependent features as well. Looks something like this:


 

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{

    using (var site = properties.Feature.Parent as SPSite)
    {

        var dependencies = (from SPFeatureDependency fd in properties.Definition.ActivationDependencies
                            let feature = SPFarm.Local.FeatureDefinitions[fd.FeatureId]
                            where feature.Hidden == true
                            select feature).ToArray();

        foreach (var dependency in dependencies)
        {
            site.Features.Remove(dependency.Id);
        }
    }

}

 

I´m using a bit of Linq here to get all the dependencies that are hidden because it´s a bit dangerous to deactivate the features that are visible because they won´t get activated by default upon re-activation so I´ll skip those.

And now, when I reactivate the “master” feature, the dependency feature also fires again and the list title is updated.

image
GREAT!!

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: