If you are writing SharePoint feature receivers often, you will find there are several lines of code common to just about every feature receiver:
- A cast of properties.Feature.Parent to the appropriate scope (either SPWeb, SPSite, SPWebApplication, or SPFarm)
- Empty implementations of FeatureInstalled and FeatureUninstalling
Provided below is an abstract generic class that now serves as the base class for every feature receiver I write. It eliminates the redundant code by performing the cast for you based on the classes generic type parameter and also goes ahead and implements all the abstract methods, making it so that you to only need to override the actual methods you plan to handle. Your extending feature receiver now will look like the following:
public class MyFeatureReceiver : BaseFeatureReceiver<SPWeb> { public override void FeatureDeactivating(SPWeb scope, SPFeatureReceiverProperties properties) { // Pointless, but what the heck base.FeatureDeactivating(scope, properties); // Now do something with your scope object, in this case an SPWeb ... } } |
And now, the code for the BaseFeatureReceiver:
/// <summary> /// Base class that makes the feature scope available as an argument to the /// FeatureActivated and FeatureDeactivating methods /// </summary> /// <typeparam name="T"> /// T is the class type of the scope of the feature (SPFarm, SPWebApplication, SPSite, or SPWeb) /// </typeparam> public abstract class BaseFeatureReceiver<T> : SPFeatureReceiver { public sealed override void FeatureActivated(SPFeatureReceiverProperties properties) { FeatureActivated((T)properties.Feature.Parent, properties); } public virtual void FeatureActivated(T scope, SPFeatureReceiverProperties properties) { } public sealed override void FeatureDeactivating(SPFeatureReceiverProperties properties) { FeatureDeactivating((T)properties.Feature.Parent, properties); } public virtual void FeatureDeactivating(T scope, SPFeatureReceiverProperties properties) { } public override void FeatureInstalled(SPFeatureReceiverProperties properties) { } public override void FeatureUninstalling(SPFeatureReceiverProperties properties) { } } |
Hope you find this helpful.
I think you can improve BaseFeatureReceiver by adding a generic argument restriction:
class BaseFeatureReceiver : SPFeatureReceiver where T : IDisposable
Then you could implement FeatureActivated and FeatureDeactivating a little better:
public sealed override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using (T parent = (T)properties.Feature.Parent)
{
FeatureActivated(parent, properties);
}
}
@Juozas
Using the generic restraint would work only for the Web and Site scopes. The SPWebApplication and SPFarm objects do not implement IDisposable.
Also, it is not necessary to dispose the SPWeb or SPSite object referenced by properties.Feature.Parent. See the following links for more details:
http://solutionizing.net/2009/02/08/do-not-dispose-spfeaturereceiverproperties-feature-parent/
http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/c0f1a05f-f1db-4f37-8f24-5966ab43e73b/
Lovely
thanks a million.
Interesting, I think it’s a bit of overkill, but it might have some other useful applications. I use Lambda functions, and extensions methods for Disposing of SPWeb and SPSite, and also disposing memory leans on traversals of objects. Some might say that is overkill too.