5

We have a number of web-scoped features all stapled to a site definition, so they are all activated in turn when a web is created from the definition.

It seems the feature receivers all share the same reference to the created web, accessed via (SPWeb)properties.Feature.Parent in the FeatureActivated method. This is normally OK - one feature receiver makes some changes to the web, updates it, and passes the updated web to the next receiver, and so on.

However, one of our features applies a ThmxTheme to the web. This involves elevating the web, which means the original web reference becomes stale. If any other feature receiver tries to make further changes to the web, an exception is thrown and the whole creation is rolled back.

At the moment, we seem to be successfully working around this by putting the ThmxTheme feature first in our feature stapler, which apparently makes the feature get activated last. I don't believe we can really rely on this.

The other way we could work around this problem is to change every feature receiver to get a clean web reference via ((SPWeb)properties.Feature.Parent).Site.OpenWeb. We don't have full control over all the features, though.

Ideally there'd be a way to refresh the single shared web reference at the end of the feature receiver that I know makes it stale, so none of the other features would have to be changed, but I don't believe this is possible.

Is there a canonical way of avoiding this problem? Can I really rely on the stapled features being activated bottom-to-top?

2
  • Why not try using a feature dependancy from feature which relys on elevation of priveleges to rely on the three other features, hiding them an only stapling the feature which is dependant on the others.
    – GavinB
    Nov 3, 2011 at 2:18
  • @GavinB: Unfortunately, one of the other features only applies to one of our site templates, while the elevation-feature applies to all of them. We can't use a feature dependency without forcing that feature to be applied to all of the templates... although this would be a great solution for the other features, which do apply to all our site templates.
    – Rawling
    Nov 3, 2011 at 8:21

1 Answer 1

3

You should dispose of the SPWeb reference after each feature receiver has executed.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    using (SPWeb web = properties.Feature.Parent as SPWeb)
    {
    }
}

Admittedly, feature receivers such as this are one of the few places where you don't "have to" dispose of your SPWeb references in SharePoint, but in your case (and I had the same issue) this will ensure that each new feature loads a fresh up-to-date copy of the parent SPWeb.

http://solutionizing.net/2008/12/06/the-new-definitive-spsitespweb-disposal-article/

2
  • I have to admit I was skeptical, but this really did seem to work. I only had to alter the problem feature receiver, which is great. I'm a little concerned as it's a "don't dispose" reference rather than a "don't have to dispose", but it doesn't seem to cause any harm and it does fix my problem!
    – Rawling
    Dec 8, 2011 at 9:46
  • Glad it worked for you!
    – user4545
    Dec 8, 2011 at 11:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.