SharePoint 2010 ALM – Part 1 – Versioning Features and Assemblies

This post was prompted by needing to explain the versioning and upgrade strategy in SharePoint 2010 to some partners we are working with at Content and Code. It ended up a very length conversation so I decided to jot it all down and split it up into 2 parts.

  • Part 1 – Feature and Assembly Versioning
  • Part 2 – Upgrading your projects for In-Place Upgrade or Side-by-Side release.

Regarding upgrading SharePoint 2010 projects there are 2 specific areas of new functionality that will key for SharePoint 2010 Application Lifecycle Management:

  • Assembly Versions
  • Feature Versions

Assembly Versions

It is typically recommended that the Assembly Version is incremented when you are upgrading / fixing / changing any of your managed code. This will however have an implication for web parts, web controls and pages across the system, but SharePoint 2010 has provisioned for that.

$SharePoint.Project.AssemblyFullName$

This is a new placeholder value that you will find all over SharePoint 2010. This includes both ASPX / ASCX  files (such as Page Layouts or Visual Web Parts, as an <% @Assembly %> tag) as well as Feature Receivers (in the Feature XML). Basically, when you package your WSP SharePoint will automatically swap out this value for the fully-qualified Assembly Reference for the current project state. This means it will swap out the full Assembly name, version number, culture and Public Key Token.

Assembly BindingRedirect element (solution manifest.xml)

Another new feature in SharePoint 2010 is the ability to specify an AssemblyBindingRedirect from the WSP.

This is part of the Manifest.xml schema (and has intellisense support in Visual Studio 2010) to allow you to automatically add new assembling binding information when a new WSP is rolled out.

Example: binding redirect to redirect version “1.0.0.0” to the current assembly version in the package:

<Assemblies>

    <Assembly Location="MyCustomAssembly.dll" DeploymentTarget="GlobalAssemblyCache">

      <BindingRedirects>

        <BindingRedirect OldVersion="1.0.0.0"/>

      </BindingRedirects>

    </Assembly>

</Assemblies>

With these two functions combined, we should have no problem upgrading an existing assembly to a new version.

You should be aware though that the Binding Redirects will only apply to the Web Application’s web.config, and therefore will NOT work for anything operating outside of the web context (such as Timer Jobs and Workflows!). This is discussed in more detail in Part 2.

Feature Versions

There are a number of new version-related parts to the Feature framework. Each feature.xml can now be given a specific Version number property (if you don’t specify then it will be given a value of 0.0.0.0). This property was listed in the WSS 3.0 SDK, but it was reserved for internal use at the time (now it finally gets some legs!)

This all stems from a new set of XML elements that you can add to the Feature.xml, starting with <UpgradeActions> element.

<VersionRange>

The first element is the Version Range .. which allows you to specify the BeginVersion and EndVersion. The actions specified in the upgrade will only be processed if the if the current version of the feature is between that range!

Typically you would wrap this element around the actions that you wish to be executed when the upgrade is performed.

<AddContentTypeField>

Pretty much as it says on the tin, this allows you to add a field to an existing Content Type.

<ApplyElementManifests>

This allows you to apply a specific element manifest when the upgrade process kicks off.

This is good because if you are adding a new element manifest (say to provision a new site column?) then you can process that specific manifest in isolation as part of your upgrade process without going off and executing all of the other manifests in the feature.

<MapFile>

According to the SDK this allows you to re-map a file in the content database to a different “ghosted” location. I suppose this is a supposed to be a quick, memory efficient way of gracefully modifying files, although I’m not sure what value this really has? (could you not just overwrite the file on the hard disk?)

<CustomUpgradeAction>

This element ties in with your Feature Receivers. There is a new method in the SPFeatureReceiver class. This method is called: FeatureUpgrading() and it allows you to execute custom code as part of your upgrade process.

(the only problem is that .. if you deploy your feature to a brand new farm and execute it “first time” from the new version .. this method does not get executed! You should really consider using the Feature Activated event to make sure it the behaviour is consistent!)

Example:

Below is an example snippet.

Here, if we are upgrading from Version 1 to Version 2 then a new field will be added to a content type, and those changes pushed down to all child content types and lists.

If we are upgrading from Version 2 to Version 3 then a new element manifest will be processed.

<UpgradeActions>

    <VersionRange BeginVersion="1.0.0.0" EndVersion="2.0.0.0">

      <AddContentTypeField

ContentTypeId="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39"

FieldId="{C6885FF1-4F70-425F-AB32-41767AB1B8CC}"

PushDown="TRUE"/>

    </VersionRange>

    <VersionRange

        BeginVersion="2.0.0.0"

        EndVersion="3.0.0.0">

      <ApplyElementManifests>

        <ElementManifest Location="UpgradeManifest.xml"/>

      </ApplyElementManifests>

    </VersionRange>

  </UpgradeActions>

With the feature upgrade framework, this should allow you to do almost anything when managing how your features are “upgraded” in a graceful way.

 

In Part 2 we will discuss how we can leverage these for two different upgrade scenarios:

  • In-Place Upgrade (replacing existing functionality)
  • Side-by-Side Installation (allowing two versions to co-exist)