Microsoft

Blog Categories

Subscribe to RSS feed

Archives

Extend SharePoint API with C# 3.0 Extension Methods

The C# 3.0 language and .NET 3.5 framework introduce several new language features. These new language constructs are useful individually in various contexts. In this blog I will show you how to use C# 3.0 extension methods to extend SharePoint (WSS/MOSS) API. The concepts are simple and once you learn them you can extend other applications in a similar manner.

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type. To learn more about Extension methods, see: http://msdn.microsoft.com/en-us/library/bb383977.aspx

Let’s start with “SPListItem” object. The SPListItem object represents an item or row in a SharePoint list. The public properties and public methods on SPListItem are documented at http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistitem_members.aspx. In addition to properties and method on SPListItem object, I would like to get creation information (Who created the item and when?) and modification information (Who last modified the item and when?). One way to accomplish this is to create a new helper class that will assist us with that.

Listing 1: Helper Class

public static class SPListItemHelper
{
public static string CreationInfo(SPListItem item)
{
return String.Format("Created on {0} by {1}",

item["Created"].ToString(),

GetNameFromSharePointField(item["Author"].ToString()));

}

public static string ModificationInfo(SPListItem item)
{
return String.Format("Last Modified on {0} by {1}",
item["Modified"].ToString(),

GetNameFromSharePointField(item["Editor"].ToString()));

}

public static string GetNameFromSharePointField(string spField)
{
return spField.Contains("#")

? spField.Substring(spField.IndexOf("#") + 1)

: spField;

}
}

Listing 2: Application with helper class

class Program
{
static void Main(string[] args)
{
using (SPSite site = new SPSite(“http://SharePoint”))
{
using (SPWeb rootWeb = site.RootWeb)
{
foreach (SPListItem Event in rootWeb.Lists[
"Events"
].Items)
{
Console.WriteLine("Event Name: " + Event.Title);
Console.WriteLine(SPListItemHelper.CreationInfo(Event));
Console.WriteLine(SPListItemHelper.ModificationInfo(Event));
Console.WriteLine();
}

Console.Read();

}
}
}
}

Listing 3: Output with helper class

clip_image002

The helper class approach is fine but it makes our code look strange and somewhat unintuitive. If CreationInfo() method and ModificationInfo()method would be on SPListItem class as instance methods then we would be able to call them without using extra calls to helper classes. It would look similar to code in listing 4.

Listing 4: Hypothetical Code

Console.WriteLine(Event.CreationInfo());
Console.WriteLine(Event.ModificationInfo());

With C# 3.0 extension methods, it is possible. If we go back to our helper class (listing 1) and specify CreationInfo() and ModificationInfo() methods’ first arguments with the “this” keyword modifier, they will become extension methods.

Listing 5: C# Extension methods for SharePoint SPListItem object

namespace ExtensionMethods
{
public static class MOSSExtensions
{

// This is an extension method. Notice the "this" keyword in the first argument.
public static string CreationInfo(this SPListItem item)
{
return String.Format("Created on {0} by {1}",

item["Created"].ToString(),

GetNameFromSharePointField(item["Author"].ToString()));

}

// This is an extension method. Notice the "this" keyword in the first argument.
public static string ModificationInfo(this SPListItem item)
{
return String.Format("Last Modified on {0} by {1}",

item["Modified"].ToString(),

GetNameFromSharePointField(item["Editor"].ToString()));

}

// This is a normal static method. Notice there is no "this" keyword in the first argument.
public static string GetNameFromSharePointField(string spField)
{
return spField.Contains("#")

? spField.Substring(spField.IndexOf("#") + 1)

: spField;

}
}
}

Notice that GetNameFromSharePointField() method’s first argument is not using the “this” keyword. Hence CreationInfo() and ModificationInfo() are extension methods and can be called on SPListItem instance directly, but GetNameFromSharePointField() is not an extension method and cannot be called directly on SPListItem instance.

Listing 6: Application with extension methods

using ExtensionMethods;

class Program
{
static void Main(string[] args)
{
using (SPSite site = new SPSite(“http://SharePoint”))
{
using (SPWeb rootWeb = site.RootWeb)
{
foreach (SPListItem Event in rootWeb.Lists["Events"].Items)
{
Console.WriteLine("Event Name: " + Event.Title);
Console.WriteLine(Event.CreationInfo());
Console.WriteLine(Event.ModificationInfo());
Console.WriteLine();
}
Console.Read();
}
}
}
}

Listing 7: Output with extension methods library

clip_image004

You can see that the output with extension method library is identical to the output we had with our helper class, but the syntax with extension methods is much more streamline and a lot easier to understand.

I hope that this blog will get you started with your own SharePoint API extensions.

Talha

Leave a Reply