Monday, July 28, 2008

LINQ Over Interwoven

Here at the large, International law firm in which I'm employed, we use Interwoven as our document management system (DMS) of choice. We've found it advantageous to expose a slice here and a slice there of Interwoven functionality via web service API's, which has become all the more easier using C# 3.0's new language improvements.

Allow me to demonstrate:

Extension Methods

If we want to use LINQ to enumerate over Interwoven's COM-based collections we need a way to easily convert them into an IEnumerable (or IQueryable). Extension method provide us with an elegant way of extending the Interwoven API so that it appears to give us IEnumerable access to its collections.

Here's a sample extension method for converting an IManage.IManFolders collection into an IEnumerable.

public static IEnumerable<IManage.IManFolder> ToIEnumerable(this IManage.IManFolders folders)
{
List<IManage.IManFolder> list = new List<IManFolder>(folders.Count);

foreach (IManFolder folder in folders)
{
list.Add(folder);
}

list.TrimExcess();

return list.AsEnumerable();
}


To really get a sense of how this makes our lives much easier as developers, let's just dive right into...


LINQ over XML


If you haven't played with LINQ over XML yet, allow me to demonstrate a smidgen of its power. This next block of code will recursively build a nested (and correctly indented) block of XML containing an Interwoven folder and all of it's child folders (using the extension method we created above).



public XElement GetFolderAsXElement(IManFolder folder)
{
return new XElement("IManFolder",
new XAttribute("Name", folder.Name),
new XAttribute("NrtId", folder.ObjectID),
new XAttribute("ObjectType", folder.ObjectType),
new XAttribute("FolderType", folder.ObjectType),
from IManFolder subFolder in folder.SubFolders.ToIEnumerable()
select GetFolderAsXElement(subFolder)
);
}


The beauty of the new .Net 3.5 XML classes (XElement, XDoc, XAttribute, et al), is in its readability. Anyone can take one look at that code and instantly understand the structure of the XML that's being created. And if you're paying close attention, you'll note that all the work being done in that function was succinctly described in only one statement!


I've heard many developers express concern over their coworkers and comrades going all rogue with these new features, particularly extension methods. But here, I think is an example where the new language features actually improve our code, and enable us to do what otherwise would have taken much longer.