By: TwitterButtons.com

Recent blog posts

User login

Home | Blogs | Stephane Eyskens's blog

Feature Upgrade : Better to go for full solution deployment or for solution upgrade?

There are already a lot of debates everywhere around the web discussing about the best strategy when it comes to solution deployment. The main topic is always Solution Upgrade (which I’ll refer further to as SU) or Solution Retract/Delete/Add/Deploy (which I’ll refer further to as FSD).

Back in the 2007 days, those debates were already present but at that time, FSD often won the battle and there were not many people envisioning seriously working with SU.
Since SharePoint 2010, for a lot of the people, SU has become the preferred strategy because of the new feature framework that leverages a new feature upgrade process.

To me, being in favor or against SU depends on your context but I don’t think that you should automatically go for SU when envisioning your feature upgrade strategy. This is what I’ll elaborate in this article.

Existing Content


Chris O’Brien wrote a series of awesome articles about handling feature upgrade. The first article can be found here http://www.sharepointnutsandbolts.com/2010/06/feature-upgrade-part-1-fun....
He also developed a valuable helper solution which is available on CodePlex http://SPFeatureUpgrade.codeplex.com.


Another fellow MVP, Jeremy Thake recorded a while ago (in beta2) a very good screencast explaining what’s going on behind the scenes with feature upgrade https://www.nothingbutsharepoint.com/sites/devwiki/Podcasts/Pages/SPWebC....
Both Jeremy and Chris do not explicitly stipulate than SU is better than FSD for feature upgrade but they both use SU in all their examples. So, we can consider it as an implicit statement :).


What I don’t like with SU


SU limitations are quite big, here is what you cannot do with SU:

  • Removing old Features in a new version of a solution
  • Say you had a WebApplication scoped feature in your previous package, you redeploy the new package and you removed that feature. The feature files will be removed from the file system but the feature will still be known as active in the SharePoint configuration database causing your file system to be out of sync with the config database.

    With a FSD, both your config database and your file system would still be in sync (in the case of a Farm/WebApplication scoped feature).

  • Adding new features in a new version of a solution
  • If you add new features, the files will be deployed to the file system but the features will not be installed. Therefore, you must add extra manual/scripted steps to explicitely install the feature which can be error prone.

  • Modifying the ID of a previously deployed feature
  • That will throw an error when trying to run the Update-Solution cmdlet

  • Modifying the scope of a previously deployed feature
  • That actually works but consider the following scenario : you have a web scoped feature already deployed. You update the scope to Site, you upgrade the existing solution package. You’ll see your new feature in the site collection features BUT, any web which you might have associated with the old web feature will remain associated….This will put your content database out of sync with the file system.
    Note that this is also true with a FSD, before retracting, you’ll have to deactivate the web feature where it’s already active. So, MSDN lists this as a SU specific limitation but IMHO, it is not.
    Other limitations are listed on MSDN http://msdn.microsoft.com/en-us/library/aa543659.aspx but some of them are not really technical limitations. For instance, changing feature properties works but this might cause a supportability issue.


What I don’t like the most is the fact that modifying and or adding/removing features isn’t handled by SU. To me, this is a big limitation because whenever you add functionality to a SharePoint application, you should use the feature framework. This limitation can be bypassed by adding Install-SPFeature (or remove…) steps in your deployment scripts but I tend to work with a KISS approach and to me, the most can be done by a solution, the better it is.
FSD does not suffer from those limitations. The only thing you have to take into account with FSD is that if you really want to completely remove a (web/site scoped) feature, you’ll have to deactivate it before effectively running the FSD. This is also a manual/scripted step but this time, you don’t have the choice :).

Why would SU be better with feature upgrade (FU) than FSD?


To me, you should choose a strategy according to the context of your project. A lot of people things that SU is the only way to go with FU because SU doesn’t “touch” the existing features while FSD and more specifically the retraction deactivates features.
This is only partially true. This deactivation is only performed for Farm/WebApplication scoped features but not for Web/Site scoped features. In a project, what is the percentage of Farm/WebApplication scoped features?
For most of my projects, 99% of the features are actually web/site scoped. Only a few are Farm/WebApplication scoped which is actually completely obvious since where are the end users going, to the central admin or to the sites? :).


So, I’m actually in favor of using FSD in my projects. FSD perfectly fits feature upgrade with features that are web/site scoped. Let’s take the simplest scenario:


Version one of a feature

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
 Title="My Web Feature" Id="e7275971-8c75-4aa4-978a-3e7e5d53cba8" 
 ReceiverAssembly="MyWebFeature" 
 ReceiverClass="$SharePoint.Type.27a87afb-0bba-431d-b1b0-cdcf8cc21c68.FullName$"
  Scope="Web" Version="1.0.0.0">
</Feature>



This web scoped feature has a receiver that will update the target web title:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
 {
            SPWeb FeatureWeb = properties.Feature.Parent as SPWeb;
            FeatureWeb.Title = "Feature activated at " + DateTime.Now.ToString();
            FeatureWeb.Update();
 }

After a F5 with Visual Studio:

You can easily see that the web title has indeed been modified.

Let’s now update the feature:

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
 Title="My Web Feature" Id="e7275971-8c75-4aa4-978a-3e7e5d53cba8"
 ReceiverAssembly="MyWebFeature, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4c8fabab55c81105"
 ReceiverClass="MyWebFeature.Features.MyWebFeature.MyWebFeatureEventReceiver"
 Scope="Web" Version="1.1.0.0">
  <UpgradeActions>
    <VersionRange>
      <CustomUpgradeAction Name="UpdateWebTitle"></CustomUpgradeAction>
    </VersionRange>
  </UpgradeActions>
</Feature>

We’ve just incremented the version and specified an upgrade action which will execute this code:

public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
        {
            if (upgradeActionName == "UpdateWebTitle")
            {
                SPWeb FeatureWeb = properties.Feature.Parent as SPWeb;
                FeatureWeb.Title = "Feature upgraded at " + DateTime.Now.ToString();
                FeatureWeb.Update();
            }
        }

Let’s now NOT DO A F5 with Visual Studio but rather package the solution, retract it, remove it and deploy it again either via PowerShell/CA or by changing settings at Visual Studio level.
Remember, our feature is still active in the content and associated to our web site.
After a FSD, just run the following piece of code (or PowerShell equivalent):

using (SPSite Site = new SPSite("http://intranet.contoso.com/ "))
            {
                var features = Site.QueryFeatures(new Guid("e7275971-8c75-4aa4-978a-3e7e5d53cba8"), true);
                IEnumerator<SPFeature> featureEnumerator = features.GetEnumerator();

                while (featureEnumerator.MoveNext())
                {                    
                    SPFeature feature = featureEnumerator.Current;                    
                    feature.Upgrade(false);                    
                }            
            }

You’ll see that the feature has been upgraded:

Although I have used FSD not SU…Why is it also working with FSD?

This is working because FSD does not deactivate/reactivate web/site scoped features. Those features are part of the content databases, meaning that when you deploy the new WSP with new versions, SharePoint is still able to compare what is known inside the content databases and what is deployed to the front end servers.


The trap



As you have probably noticed, no matter which solution deployment you choose, the real conflict with feature upgrade is when features get deactivated/activated automatically. SU doesn’t change the state of the features whatever scope they are deployed to. FSD however does it for WebApplication/Farm scoped features…

The feature property ActivateOnDefault can be set to TRUE or FALSE. It has no impact on web/site scoped features but does have one on WebApplication/Farm scoped features.

When set to FALSE, those features are not automatically activated upon solution deployment but they are automatically deactivated upon solution retraction…which therefore conflicts with feature upgrade because the only option left is to reactivate the feature....
I don’t really understand the added value of that property since for me, it should have a consistent behavior. If you choose not to have them activated automatically, they should not be deactivated automatically…



The good catch...



A good catch from one of my Colleagues Tom Nys http://tomblog.insomniacminds.com/ is that when using FSD, since farm/webapplication scoped features are automatically deactivated, if there is a feature receiver, the corresponding DLL will be loaded by PowerShell (if using PowerShell) inside the current process during solution retraction.
The problem is that after having added/deployed the new package, the old DLL is still loaded in memory and therefore, performing a feature activation would relaunch the old code instead of the new one...In that case, when dealing with FSD and farm/webapplication scoped features, you should run all the deactivation/retraction steps in one process and the add/deploy/activation steps in another one.


Conclusion


I’m in favor of using FSD whenever possible but as you’ve seen it, this could be an issue if you plan to use featureupgrade with WebApplication/FarmScoped features.
On the other hand, as already mentioned, the percentage of such scoped features in usually very low. So, you have to choose between :

  • Having to support the limitations of SU but having the comfort when upgrading Farm/WebApplication features
  • Not having limitations of SU but having to deal the old school way to “upgrade” Farm/WebApplication features (by handling the “upgrade” at feature deactivation/reactivation).


My choice is done based on the percentage of Farm/WebApplication features I have, refined by the percentage of those that might effectively require an upgrade. If I end up with <=5%, then I prefer to go for FSD and avoid all the limitations of SU but still being able to handle perfectly feature upgrade for my site collections and webs

Happy Coding!