Content Deployment aware feature receiver
Today I was testing a content deployment job in SharePoint 2007 and the job finished successfully. When I looked at the content I found that the property bag of a web contained values I wasn’t expecting. When I looked at the order in which the content deployment is executed I understood why. During the import phase of content deployment the features are activated after the property bag is imported. In my feature receiver I have built some functionality to copy settings from the property bag of the parent web to the current web. This functionality overwrites the imported settings.
The answer to my problem was to create a content deployment aware feature receiver. So I started to look around on the internet and found the SPImportContext class. But this class is only available in SharePoint 2010. So I needed some other functionality.
To find out what happened during the import phase, I attached my debugger to the SharePoint Timer Service (owstimer). I then activated a breakpoint in the FeatureActivated event. When I looked at the current stack I could see that the feature receiver was called from the ContentDeploymentJob. I came up with the following function to detect if the feature receiver (and/or event receiver) is running in the ContentDeploymentJob.
/// <summary> /// Detects if the stack is called from a <see cref="ContentDeploymentJob"/>. /// </summary> /// <returns> /// A value indicating whether the current code is called from /// the <see cref="ContentDeploymentJob"/>. /// </returns> public static bool IsContentDeploymentRunning() { var stackTrace = new StackTrace(); var stackFrames = stackTrace.GetFrames(); if (stackFrames != null) { foreach (var stackFrame in stackFrames) { if (stackFrame.GetMethod().ReflectedType == typeof(ContentDeploymentJob)) { return true; } } } return false; }
The feature receiver now uses this function as follows:
[SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)] public override void FeatureActivated(SPFeatureReceiverProperties properties) { if (IsContentDeploymentRunning()) { return; } .... }

