WSS Event Handlers Flexible Feature Install

Hi and welcome to my blog, my first post its about a flexible way of installing event handlers as a feature in WSS using stsadm command.

I’ve been investigating the best way to create a event handler feature receiver without hard coding the target lists and the event receiver assembly name. In my point of view this is a much better approach than the hard coding simply because when installing the event handler thought the stsadm command if we want to add or remove a target list simply go to the features.xml and change a xml element.

What I do is create three feature properties in feature.xml like this:
<Feature Id="6EC7FC10-058F-40f4-AC86-87E0EA4189ED" …>
<Properties>
<Property Key = "TargetList" Value = "List1;List2;List3"/>
<Property Key = "EventReceiverAssembly" Value = "EventHandlers.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=387e5ebd0bdeaef9"/>
<Property Key = "EventReceiverClass" Value = " EventHandlers.Assembly.DemoHandler"/>
</Properties>
</Feature>

Then in the FeatureActivated method in Feature Receiver class I get all the properties I need from the feature and then split the target list property by ‘;’, for each list add the event receiver using the method “AddEventReceiverToList” where I’ll pass the event receiver assembly name and class. Finally create a new feature property wich key is “ReceiverID_[ListName]” to use the feature deactivation.
In the feature deactivation the process is the same, get the target list property and for each list get the receivers id’s and delete the event receiver from the list.

Here’s the code:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPFeature feature = properties.Feature;
string targetList = feature.Properties[Constants.FeatureProperties.TargetList].Value;
string eventReceiverAssembly = feature.Properties[Constants.FeatureProperties.EventReceiverAssembly].Value;
string eventReceiverClass = feature.Properties[Constants.FeatureProperties.EventReceiverClass].Value;
Assert.IsFalse(string.IsNullOrEmpty(targetList), "Feature ‘{0}’ ‘TargetList’ property is empty.", feature.DefinitionId);
Assert.IsFalse(string.IsNullOrEmpty(eventReceiverAssembly), "Feature ‘{0}’ ‘EventReceiverAssembly’ property is empty.", feature.DefinitionId);
Assert.IsFalse(string.IsNullOrEmpty(eventReceiverClass), "Feature ‘{0}’ ‘EventReceiverClass’ property is empty.", feature.DefinitionId);
using (SPWeb web = (SPWeb)feature.Parent)
{
string[] listsStr = targetList.Split(‘;’);
foreach (string listStr in listsStr)
{
SPList list = web.Lists[listStr];
Guid itemAddedReceiverId = AddEventReceiverToList(list, SPEventReceiverType.ItemAdded, eventReceiverAssembly, eventReceiverClass);
Guid itemUpdatedReceiverId = AddEventReceiverToList(list, SPEventReceiverType.ItemUpdated, eventReceiverAssembly, eventReceiverClass);
//To use in Deactivation
string receiverIdsKey = string.Format("{0}_{1}", Constants.FeatureProperties.ReceiversIds, listStr);
feature.Properties.Add(new SPFeatureProperty(receiverIdsKey, string.Concat(itemAddedReceiverId, ";", itemUpdatedReceiverId)));
feature.Properties.Update();
Logger.Log("Handler ‘{0}’ added on list: ‘{1}’", EventHandlerName, list.Title);
}
}
Logger.Log("’{0}’ Successfuly Activated", EventHandlerName);
}
catch (Exception ex)
{
Logger.Error(ex, "Error Activating handler ‘{0}’", EventHandlerName);
throw;
}
}
private Guid AddEventReceiverToList(SPList spList, SPEventReceiverType receiverType, string assemblyName, string className)
{
Guid receiverId = Guid.NewGuid();
SPEventReceiverDefinition receiver = spList.EventReceivers.Add(receiverId);
receiver.Assembly = assemblyName;
receiver.Class = className;
receiver.Type = receiverType;
receiver.Update();
return receiverId;
}

In my opinion this is a much more flexible way of installing event handlers to wss with stsadm without hard coding.

If anyone have any other alternatives/sugestions please tell me about it.

Hope this helps,
Romano

Advertisements