Why You Need Reflector: SPList.DefaultView

I love Reflector. It has been invaluable in my various continuous learning efforts, poking around interesting code to improve my own. However, the need for Reflector spans beyond curiosity: when working with the SharePoint object model, it is an essential tool to understand what’s going on behind the scenes. It would be great if the API always did what you expect, or at least documented some of its less-than-obvious behavior, but it doesn’t and probably never will. It’s simply too big and “what you expect” is often a matter of opinion.

An excellent example is the behavior of SPList.DefaultView. As recently discovered by Andy Burns and earlier documented by Daniel Pavelescu, DefaultView returns a new SPView instance on every call. So instead of this:

list.DefaultView.ViewFields.Add("SomeField");
list.DefaultView.Update();

You need to do this:

SPView defView = list.DefaultView;
defView.ViewFields.Add("SomeField");
defView.Update();

Daniel was able to verify this behavior with the VS debugger, but it’s not clear why. Enter Reflector:

  1. SPList.DefaultView:
    public SPView DefaultView
    {
        get
        {
            return this.Views.DefaultView;
        }
    }
  2. SPViewCollection.DefaultView:
    internal SPView DefaultView
    {
        get
        {
            if (this.m_iDefaultViewIndex != -1)
            {
                return this[this.m_iDefaultViewIndex];
            }
            return null;
        }
    }
  3. SPViewCollection.Item[Int32]
    public SPView this[int iIndex]
    {
        get
        {
            if ((iIndex < 0) || (iIndex >= this.Count))
            {
                throw new ArgumentOutOfRangeException();
            }
            return new SPView(this, this.m_arrViewSchema, iIndex);
        }
    }

In three clicks we see exactly what the problem was and why. Since I usually have Reflector open, this is almost always faster than asking Google or MSDN. Of course some methods are obfuscated (code can’t be disassembled), but fortunately these are exceptions rather than the rule.

Exploring SPView.ViewFields

As another example of code not behaving as expected, consider the implementation of SPView.ViewFields:

public SPViewFieldCollection get_ViewFields()
{
    if (this.m_xdView != null)
    {
        while (this.m_bFullBlownXmlDoc)
        {
            return new SPViewFieldCollection(this, this.Node);
        }
    }
    return new SPViewFieldCollection(this, this.GetInnerXmlForNode("ViewFields"));
}

Given that a new collection is created each time, one might expect the following to add only the second field:

SPView defView = list.DefaultView;
defView.ViewFields.Add("FirstField");
defView.ViewFields.Add("SecondField");
defView.Update();

But, much to my surprise, both fields are added! So what’s going on here? Well, let’s explore a bit with PowerShell:

PS 1> $w = spw http://localhost
PS 2> $l = $w.Lists['Test']
PS 3> $dv = $l.DefaultView
PS 4> $vf1 = $dv.ViewFields
PS 5> $vf2 = $dv.ViewFields
PS 6> $vf1
Attachments
LinkTitle
PS 7> $vf1.Add('Editor')
PS 8> $vf2
Attachments
LinkTitle
Editor

So we store two different SPViewFieldCollection objects, update one, and the other is updated as well. In my mind, this begs two questions:

  1. Why doesn’t SPView just store a reference to a shared collection?
  2. How are the collections kept in sync?

It’s tough to guess why, but Reflector can probably help us figure out how. Let’s start with one of the constructors called by ViewFields:

internal SPViewFieldCollection(SPView view, string innerXml)
{
    this.m_View = view;
    this.m_ViewStyle = null;
    this.m_strInnerXml = innerXml;
}

Not much to see here, other than the captured reference to the parent SPView. Using Reflector’s Analyze function (Ctrl-R), we see that m_strInnerXml is also referenced in the SchemaXml property:

Analyzing SPViewFieldCollection.m_strInnerXml

Which disassembles as…

public string get_SchemaXml()
{
    if (this.m_node == null)
    {
        return this.m_strInnerXml;
    }
    return this.m_node.InnerXml;
}

So the value passed in is only used if m_node has not been set. Ctrl-R again:

Analyzing SPViewFieldCollection.m_node

Now we’re getting somewhere. The members rely on EnsureViewFields() to keep up-to-date:

private void EnsureViewFields()
{
    if (this.m_node != null)
    {
        this.m_iCount = this.m_node.ChildNodes.Count;
    }
    else
    {
        this.m_View.EnsureFullBlownXmlDocument();
        this.InitViewFields(this.m_View.Node);
    }
}

And the node connection is set up in InitViewFields using its view’s Node. So SPViewFieldCollection doesn’t even have an internal data store! Instead, everything operates against m_node, which is attached to the parent view. Thus changes to one collection are immediately reflected in other collections created from the same SPView.

I still prefer to capture and reuse the SPViewFieldCollection, but at least now we know that it’s safe not to and, more interestingly, why that’s the case.

Time to share! When has Reflector saved you from SharePoint headaches?

Thinking Functional: Using

In the comments of my last post, Peter Seale pointed me to Matthew Podwysocki‘s implementation of GenerateUsing as functional abstraction of using. I like the idea, but the Generator pattern isn’t particularly useful for common SharePoint tasks. However, I think we can get some value from looking at a more generalized solution.

But first, let me suggest a minor correction to Matt’s version of Generate, at least if it’s going to be used to fulfill an IDisposable contract:

public static IEnumerable<TResult> Generate<T, TResult>(Func<T> opener,
                                                        Func<T, Option<TResult>> generator,
                                                        Action<T> closer)
{
    var openerResult = opener();
    bool stop = false;

    while (true)
    {
        var res = Option<TResult>.None;
        try
        {
            res = generator(openerResult);
        }
        finally
        {
            if (stop = res.IsNone)
                closer(openerResult);
        }
        if (stop)
            yield break;

        yield return res.Value;
    }
}

The stop “hack” is needed because you can’t yield from a finally clause. It seems to me that a closer that might not get called isn’t much of a closer, or am I missing something?

So how else might we use this opener/closer idea? How about something like this:

public static void Process<T>(Func<T> opener,
                              Action<T> action,
                              Action<T> closer)
{
    T openerResult = opener();
    try
    {
        action(openerResult);
    }
    finally
    {
        if (closer != null)
            closer(openerResult);
    }
}

public static void Using<T>(Func<T> opener,
                            Action<T> action
                           ) where T : IDisposable
{
    Process(opener, action, x => x.Dispose());
}

We have now abstracted the idea of a using statement: get the object, do something with it, Dispose(). Abstraction in hand, let’s apply it to SharePoint:

public static void ProcessWeb<TResult>(this SPSite site,
                                       string url,
                                       Action<SPWeb> action)
{
    Using(() => site.OpenWeb(url), action);
}

Now, one could argue that we haven’t gained much over the obvious implementation:

    using(SPWeb web = site.OpenWeb())
        action(web);

But in truth, the vast majority of functional code has a non-functional alternative. It’s just a different thought process. In the former, we specify what we’re trying to do: use the result of site.OpenWeb() to do action. In the latter, we specify how to do it: use an SPWeb named web, assigned from site.OpenWeb(), to perform action. I’m not saying either approach is more correct, just different means to the same end.

Performing actions is all well and good, but we often want to get something back as well:

public TResult Select<T, TResult>(Func<T> opener, Func<T, TResult> selector, Action<T> closer)
{
    T openerResult = opener();
    try
    {
        return selector(openerResult);
    }
    finally
    {

        closer(openerResult);
    }
}

public TResult SelectUsing<T, TResult>(Func<T> opener,
                                       Func<T, TResult> selector,
                                       Action<T> closer
                                      ) where T : IDisposable
{
    return Select(opener, selector, x => x.Dispose());
}
public static TResult SelectFromWeb<TResult>(this SPSite site,
                                             string url,
                                             Func<SPWeb, TResult> selector)
{
    return SelectUsing(() => site.OpenWeb(url), selector);
}

What do you think? Useful?

SPTDD: On Good Vs. Testable Code

First, my position on SharePoint Test Driven Development: I don’t currently use it. I got a free Isolator license (thanks!) that I have yet to install (sorry!). Just like everyone else, I’m trying to figure out where TDD fits in the context of SharePoint. Any assertions in this post about TDD are based on my current understanding, which is incomplete at best.

This post is in response to a post by Eric Shupps: SPTDD: SharePoint and Test Driven Development, Part One. He has a lot to say, so let’s start with this assertion:

…in order to get real value from TDD in SharePoint you must already know how to write good code. All the unit tests in the world won’t change this fact. And the only way to learn how to write good code is to do it over and over again, gathering knowledge along the way from those who have gone before you. This leads the the fundamental problem with TDD as a methodology – it doesn’t teach developers how to write good code; rather, it teaches them how to write testable code.

I agree with the differentiation between good and testable code, but I think Eric underestimates the value of testable code in relation to its goodness. For reference, let’s bring in how his example code “should be written”:

private SPListItemCollection GetListItems(string Url, string ListName)
{
    SPListItemCollection coll = null;
    try
    {
        if (Url != String.Empty && ListName != String.Empty)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(Url))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        try
                        {
                            SPList list = web.Lists[ListName];
                            if (list.Items.Count > 0)
                            {
                                coll = list.Items;
                            }
                        }
                        catch (System.Exception ex)
                        {
                            LogError(ex.Message);
                        }
                    }
                }
            });
        }
    }
    catch (System.Exception ex)
    {
        LogError(ex.Message);
    }
    return coll;
}

I know “good code” is subjective, but this method has some real problems:

  • SP* objects should not be passed out of a RWEP block.
  • SP* objects should not be used after their parent SPWeb has been disposed.
  • Each call to list.Items will execute a new query. Instead, store it to a variable or use list.ItemCount.

These issues have nothing to do with testability. They’re simply not good SharePoint code. But TDD wouldn’t fix them, so for the purpose of argument let’s use this code instead (essentially Eric’s original plus error handling):

private SPListItemCollection GetListItems(string Url, string ListName)
{
    SPListItemCollection coll = null;
    try
    {
        if (Url != String.Empty && ListName != String.Empty)
        {
            SPSite site = new SPSite(Url);
            SPWeb web = site.OpenWeb();
            try
            {
                SPList list = web.Lists[ListName];
                SPListItemCollection items = list.Items;
                if (items.Count > 0)
                {
                    coll = items;
                }
            }
            catch (System.Exception ex)
            {
                LogError(ex.Message);
            }
        }
    }
    catch (System.Exception ex)
    {
        LogError(ex.Message);
    }
    return coll;
}

So supposing we used TDD, a method like this would have been created based on tests written to verify the following:

  • If Url or ListName are empty, return null.
  • If Url or ListName are null, use them anyway and log the resulting exception.
  • Create SPSite and SPWeb that the caller needs to remember to dispose.
  • If the list has no items, return null, otherwise return all items.
  • If anything goes wrong, log the exception and return null.

I would guess this isn’t exactly what Eric intended the method to do (at least regarding null arguments), but the hypothetical tests drove the TDD implementation; a different set of tests would have led to a more correct version of the method. Herein lies the problem with critiquing TDD based on code developed without tests—TDD would likely yield a different implementation!

Abstraction and Dependency Injection = Artifacts?

I also take issue with this passage:

Look closely – the code itself satisfies all the test requirements without requiring any level of abstraction, dependency injection, nUnit, or other such artifices.

[Irony: artifice – n. Cleverness or skill; ingenuity.]

Regarding satisfaction of the requirements, the obvious question is: How do you know? Without a test, you don’t, and to think you do just because you “already know how to write good code” is more naive than thinking unit-tested SharePoint code is bulletproof. Case in point: null arguments. But more importantly, when did abstraction and dependency injection become TDD things? These are basic programming principles, completely independent from TDD or SharePoint! Just because we’re developing against a specific (and complicated) API doesn’t mean the general best practices don’t apply. We should be .NET developers first, SharePoint developers second. Even without using TDD, I submit that your particular code could benefit quite a bit from dependency injection:

private SPListItemCollection GetListItems(SPWeb web, string listName, SPQuery query)
{
    if (web == null || string.IsNullOrEmpty(listName))
        return null;
    SPListItemCollection coll = null;
    try
    {
        SPList list = web.Lists[listName];
        SPListItemCollection items = query == null ? list.Items : list.GetItems(query);
        if (items.Count > 0)
        {
            coll = items;
        }
    }
    catch (Exception ex)
    {
        LogError(ex.Message);
    }
    return coll;
}

Instead of creating an SPWeb that needs to be disposed by the caller, we just accept one that the caller should already be handling. Instead of always using list.Items (not recommended), we accept an optional SPQuery. The method has a clear purpose, doesn’t have the new SPSite to handle, works just as well with an elevated SPWeb, etc. It’s simply a better design, with improved testability being more of a side benefit than the main goal. I can’t say for sure, but I would guess a TDDed version (given the right requirements) would be similar.

On Mocking

Again, I haven’t found time to try out Isolator so I can’t really speak to the actual practice of testing mocked objects; however, it seems to me that it would be useful to verify that, given certain assumptions about a SharePoint environment, tests pass. If I can copy/paste a few lines of code to fake an SPWeb, with or without a named list, with or without list items, this seems like it would be much easier than actually creating and deleting lists and items to verify that my code behaves accordingly. Then as long as I’m in an environment that matches an assumption I tested, I’m assured the code will work as expected. Isolator seems to enable this sort of test with relative ease, at which point the general arguments for (and against) testing and TDD can be applied to SharePoint without much translation.

All that said, thanks to Eric for posting his thoughts to spark a more public discussion. Also, check out Andrew Woodward‘s first rebuttal and other posts on SharePoint and TDD (particularly Unit Testing SharePoint Solutions – Getting into the SharePoint Object Model).

Faking SPContext

A common question is how to fake SPContext in a non-SharePoint context. An answer is found at the bottom of a great post on Structured and repeatable deployment of Content Query Web Part instances, but Google doesn’t seem to find it so hopefully this will help. The whole article is worth a read, but for those looking for a quick answer:

public static SPContext FakeSPContext(SPWeb contextWeb)
{
  // Ensure HttpContext.Current
  if (HttpContext.Current == null)
  {
    HttpRequest request = new HttpRequest("", web.Url, "");
    HttpContext.Current = new HttpContext(request,
      new HttpResponse(TextWriter.Null));
  }

  // SPContext is based on SPControl.GetContextWeb(), which looks here
  if(HttpContext.Current.Items["HttpHandlerSPWeb"] == null)
    HttpContext.Current.Items["HttpHandlerSPWeb"] = web;

  return SPContext.Current;
}

I’ve made two slight modifications to Waldek’s original code:

  1. Since we don’t care about the response, we can use TextWriter.Null instead of allocating a new StringWriter().
  2. By separating the HttpContext and SPContext logic, we can use this in non-SharePoint web contexts as well as non-web contexts like unit tests and timer jobs.

While this works well for a SPWeb-based SPContext, I have not figured out how to fake a list- or item-level SPContext. It should go without saying that trying to inject a different SPWeb into an existing SPContext is a really bad idea. And finally, it is your responsibility to ensure disposal of the SPSite and SPWeb you create for the fake context.

Faking SPContext might be a necessity to work with others’ code (like CQWP), but if you’re needing to use this to work with code you own, consider refactoring to use dependency injection instead.

ServerContext and Dependency Injection

I was reviewing some code today and came across a perfect case study for Dependency Injection. It also required another peak under the hood of Microsoft.Office.Server.ServerContext, the results of which I thought might be worth sharing.

From MSDN,  ServerContext “provides run-time methods for shared services in Microsoft Office SharePoint Server 2007.” If you’re not familiar with Shared Service Providers, Shane Young has a concise overview or check out Ted Pattison‘s developer overview on MSDN. The SSP APIs span several namespaces:

  • Microsoft.Office.Excel.Server
  • Microsoft.Office.Server.ApplicationRegistry (Business Data Catalog)
  • Microsoft.Office.Server.Audience
  • Microsoft.Office.Server.Search
  • Microsoft.Office.Server.UserProfiles (includes My Sites)

The entry point to all of these APIs is ultimately a ServerContext object, made available through several static methods and properties:

  • ServerContext.Default
    Returns a new instance for the local farm’s default provider.
  • ServerContext.Current
    Returns ServerContext.GetContext(HttpContext.Current).
  • ServerContext.GetContext(HttpContext httpContext)
    Returns a shared ServerContext instance for the given request context. The provider is determined first through the microsoft.office.server/sharedService section in Web.config, and from the context WebApplication if that fails.
  • ServerContext.GetContext(WebApplication webApplication)
    Returns a new instance for the web application’s provider or the farm’s default provider if one is not specified.
  • ServerContext.GetContext(SPSite site)
    Returns ServerContext.GetContext(site.WebApplication).
  • ServerContext.GetContext(String sharedResourceProviderName)
    Returns a new instance for the named provider if it exists, either in the local farm or its parent.

These details inform some simple usage guidelines:

  1. If you have an HttpContext, use the shared instance from GetContext(HttpContext) or ServerContext.Current.
  2. If you need a specific SSP, use an overload of GetContext().
  3. Else, use ServerContext.Default.

Code Review

The code I was reviewing today was replacing this…

SearchContext.GetContext(SPContext.Current.Site)

…with this…

SearchContext.GetContext(ServerContext.Default)

…to support use of the service in a non-web context. We’re currently working with a single SSP, so Default should be sufficient; however, we can do better. First, the change in question had to be made in several places. For maintainability, it makes more sense to define a field or property to represent the context wherever we need it. Second, by using ServerContext.Default we’re missing out on the benefits of the shared instance provided for an HttpContext, which we usually have.

Dependency Injection

The Dependency Inversion Principle suggests that we should decouple the source of our ServerContext object from how its consumption. What would that look like here? Well the simplest approach is constructor injection:

private ServerContext { get; set; }
public MyService(ServerContext context)
{
    this.ServerContext = context;
}

This is the purest form of DI in that the class knows nothing about where the ServerContext came from, but it’s often practical to “cheat” and expose a nicer interface. In my case, I chose to supplement that constructor with two others:

public MyService() : this(ServerContext.Default) {}

public MyService(HttpContext httpContext)
       : this(ServerContext.GetContext(httpContext) {}

Now my web part can just call MyService(this.Context) and we still have a convenient default constructor for use in PowerShell. Because everything should be usable from PowerShell. This same idea can be applied to a number of common SharePoint tasks, particularly anywhere you’re using SPContext.Current, with benefits including improved reusability, maintainability and testability.

Do Not Dispose SPFeatureReceiverProperties.Feature.Parent

I can’t find a dedicated post about it, so I thought I’d draw attention to this thread in the MSDN forums where Michael Washam [MSFT] replied…

Do not dispose properties.Feature.Parent..

However, if you use .ParentWeb or anything else the same rules apply..

Now, the rule for SPWeb.ParentWeb is that it should not be disposed if you don’t own the child SPWeb, which we don’t, but you get the idea. It would be great if SPDisposeCheck would catch this—Roger?

I only point it out specifically because feature receiver examples are often posted online and I see Parent disposed all the time.

SPDisposeCheck Is Not A Shortcut

If you’re a SharePoint developer and you haven’t heard about the release of SPDisposeCheck, there are a number of blogs (like the SharePoint Team) you should be reading instead of (or hopefully in addition to) mine. Everyone is understandably enthusiastic—memory management is important and the rules are tricky. However, I’m afraid this is being viewed as something it’s not. To quote Tony Bierman‘s comment on Paul’s post:

I think there should be a “SPDisposeCheck Certified” logo.  This badge could be placed on the download pages and in the documentation of both free software and commercial software products as an indication of quality and adherence to best practices.

Let’s be clear: SPDisposeCheck is not definitive. It is a static analysis tool tuned to specific rules documented on the often-cited Patterns By Example. That post has been through perhaps a dozen iterations in the last year, updated as recently as last week. The team has no doubt put a lot of work into it (thanks for that), but there’s no reason to expect the guidance won’t be changed again.

Furthermore, there are countless perfectly safe code patterns, the so-called “false positives”, that will be reported as leaks. The documentation cites SPContext.Web.Site as an example, and I could probably rattle off a dozen more if pressed to do so. If the developer doesn’t investigate and just “fixes” every warning with using, more harm is done than good!

The tool will certainly be updated with the latest guidance, and the false positives will be addressed over time, but the core problem still remains: SPDisposeCheck will never know your code as well as you should. I’m sure thousands of leaks will be fixed because of it, and I’m not trying to diminish its value as part of a developer’s toolbox. Just don’t get caught thinking that passing SPDisposeCheck is a substitute for knowing what you’re doing.

That said, a big thanks to Roger, Stefan, Paul and the rest of the SPDisposeCheck team for their efforts to improve their documentation and the quality of our custom code.

Generic Method Invocation with Expression Trees

It’s against the rules and completely unsupported, but sometimes it’s just so much easier to use a base class’s private/internal members. Reflection has always been an option, but performance is less than ideal. Lightweight Code Generation is an option, but emitting IL isn’t for everyone. Since .NET 3.5 came out, there have been several discussions of using expression trees as a developer-friendly yet efficient alternative. There is an up-front cost to compile the expression into IL, but the resulting delegate can be reused with performance very close to direct invocation.

Alkampfer provides a great overview of expression tree method invocation in this article, which inspired this more general solution.

First, let’s set up a cache to store our compiled delegates. I didn’t put much effort into making it efficiently thread-safe, but suggestions are certainly welcome.

private static Dictionary<string, Delegate> accessors = new Dictionary<string, Delegate>();
private static object accessorLock = new object();
private static D GetCachedAccessor<D>(string key)
                 where D : class // Constraint cannot be special class 'System.Delegate'
{
    D result = null;
    Delegate cachedDelegate;
    lock (accessorLock)
    {
        if (accessors.TryGetValue(key, out cachedDelegate))
        {
            Debug.WriteLine("Found cache entry for " + key);
            result = cachedDelegate as D;
        }
    }
    return result;
}
private static void SetCachedAccessor(string key, Delegate value)
{
    if (value != null)
        lock (accessorLock)
        {
            accessors[key] = value;
        }
}

GetFieldAccessor

Now we can dive into our expression trees. As a warm-up, here’s a relatively simple cached field accessor, inspired by Roger Alsing‘s great post:

public static Func<T, R> GetFieldAccessor<T, R>(string fieldName)
{
    Type typeT = typeof(T);

    string key = string.Format("{0}.{1}", typeT.FullName, fieldName);
    Func<T, R> result = GetCachedAccessor<Func<T, R>>(key);

    if (result == null)
    {
        var param = Expression.Parameter(typeT, "obj");
        var member = Expression.PropertyOrField(param, fieldName);
        var lambda = Expression.Lambda<Func<T, R>>(member, param);

        Debug.WriteLine("Caching " + key + " : " + lambda.Body);
        result = lambda.Compile();
        SetCachedAccessor(key, result);
    }
    return result;
}

The method returns a function that will accept an object of type T and return its fieldName property with type R. For example, we can wrap this in an extension method to check if an SPWeb has been disposed:

public static bool GetIsClosed(this SPWeb web)
{
    return GetFieldAccessor<SPWeb, bool>("m_closed")(web);
}

Because the delegate is cached, successive calls of GetFieldAccessor() will immediately return the necessary delegate without recompilation.

GetMethodAccessor

Building a method accessor is a bit trickier because of the various combinations of parameter and return types. One option is to explicitly define overloads for various method signatures, as seen in the article referenced earlier. Instead, I figure we can let the caller specify the desired delegate signature and figure out the intended method based on that.

public static D GetMethodAccessor<D>(string methodName, BindingFlags bindingAttr)
                where D : class // Constraint cannot be special class 'System.Delegate'
{
    Type[] args = typeof(D).GetGenericArguments();
    Type objType = args[0];

    Type[] argTypes = args.Skip(1).ToArray();
    string[] argTypesArray = argTypes.Select(t => t.Name).ToArray();
    string key = string.Format("{0}.{1}({2})", objType.FullName, methodName, string.Join(",", argTypesArray));

    D result = GetCachedAccessor<D>(key);
    if (result == null)
    {
        MethodInfo mi = objType.GetMethod(methodName, bindingAttr, null, argTypes, null);

        if (mi == null || mi.ReturnType != typeof(void))
        {
            argTypes = argTypes.Take(argTypesArray.Length - 1).ToArray();
            mi = objType.GetMethod(methodName, bindingAttr, null, argTypes, null);
        }

        if (mi == null)
            throw new ArgumentException("Could not find appropriate overload.", methodName);

        var param = Expression.Parameter(objType, "obj");
        var arguments = argTypes.Select((t, i) => Expression.Parameter(t, "p" + i)).ToArray();
        var invoke = Expression.Call(param, mi, arguments);
        var lambda = Expression.Lambda<D>(invoke, param.AsEnumerable().Concat(arguments));

        Debug.WriteLine("Caching " + key + " : " + lambda.Body);
        result = lambda.Compile();
        SetCachedAccessor(key, result as Delegate);
    }
    return result;
}

As you can see, we depend heavily on the generic arguments of the delegate type. This means passing a closed delegate type to this function won’t work – it needs to be Func, Action, or something compatible with the expected argument structure. So what is that structure? The processing logic works like this:

  1. Take the first generic argument as the type whose method we are going to invoke.
  2. Fetch an array, skipping the first argument, that we pass to GetMethod as the argument types.
  3. If GetMethod can’t find an appropriate overload, or if the method’s return type is not void, then we shouldn’t have used all of the arguments as parameters.
  4. Redefine our parameter array without the last argument – this is our delegate’s non-void return type.
  5. Try GetMethod again with the trimmed array; throw if we still don’t find a match.

Once we have the details of our method, we can build the expression tree. I use the mapi-style Select overload to build an array of typed parameters named p0, p1, etc., which is then passed to Expression.Call to represent the method invocation. Finally, Expression.Lambda expects a list of all parameters including the instance param. Rather than allocate an intermediate data structure, I use a trick I picked up from Keith Rimington:

public static IEnumerable<T> AsEnumerable<T>(this T obj)
{
    yield return obj;
}

By turning param into a single-element IEnumerable<ParameterExpression>, we can simply Concat the rest of the arguments. Beautiful.

GetMethodAccessor Usage

The usage is a bit more complex then GetFieldAccessor, but still quite manageable:

public static bool SetBoolValue(this SPField field, string attrName, bool attrValue)
{
    Func<SPField, string, bool, bool> lambda =
        GetMethodAccessor<Func<SPField, string, bool, bool>>("SetFieldBoolValue",
                                                             BindingFlags.Instance | BindingFlags.NonPublic);
    return lambda(field, attrName, attrValue);
}

The intermediate variable is unnecessary, but makes it easier to see what’s going on. SPField.SetFieldBoolValue is of type Func<string, bool, bool>, so our delegate needs to be Func<SPField, string, bool, bool> to accept the instance variable first. The parameters for GetMethodAccessor are identical to what we would pass to field.GetType().GetMethod() if we were using normal reflection. Then we invoke lambda to effectively call field.SetFieldBoolValue(attrName, attrValue).

For methods that return void, we just pass an Action type instead:

public static void SetHidden(this SPField field, bool value)
{
    GetMethodAccessor<Action<SPField, bool>>("SetHidden", BindingFlags.Instance | BindingFlags.NonPublic)(field, value);
}

And these can be used like any other extension methods:

SPField field = GetField();
field.SetBoolValue("CanToggleHidden", !field.CanToggleHidden);
field.SetBoolValue("CanBeDeleted", !field.CanBeDeleted);
field.SetHidden(!field.Hidden);
field.Update();

Which will show the following in DebugView:

Caching Microsoft.SharePoint.SPField.SetFieldBoolValue(String,Boolean,Boolean) : obj.SetFieldBoolValue(p0, p1)
Found cache entry for Microsoft.SharePoint.SPField.SetFieldBoolValue(String,Boolean,Boolean)
Caching Microsoft.SharePoint.SPField.SetHidden(Boolean) : obj.SetHidden(p0)

Because of the penalty for compilation, this technique is not right for all situations. But for frequent access to inaccessible members, it might be worth a try.

LINQ Tip: Enumerable.OfType

In the past I’ve mentioned LINQ’s Cast<T>() as an efficient way to convert a SharePoint collection into an IEnumerable<T> that has access to LINQ’s various extension methods. Fundamentally, Cast<T>() is implemented like this:

public IEnumerable<T> Cast<T>(this IEnumerable source)
{
  foreach(object o in source)
    yield return (T) o;
}

Using an explicit cast performs well, but will result in an InvalidCastException if the cast fails. A less efficient yet useful variation on this idea is OfType<T>():

public IEnumerable<T> OfType<T>(this IEnumerable source)
{
  foreach(object o in source)
    if(o is T)
      yield return (T) o;
}

The returned enumeration will only include elements that can safely be cast to the specified type. Why would this be useful?

Example 1: SPWindowsServiceInstance

SharePoint, especially with MOSS, has several different services that can run on the various servers in a farm. We know where our web services are running, but where are the various windows services running?

var winsvc = from svr in SPFarm.Local.Servers
             from inst in svr.ServiceInstances.OfType<SPWindowsServiceInstance>()
             select new
             {
                 Server = svr.Name,
                 ID = inst.Id,
                 ServiceType = inst.Service.GetType().Name
             };

Example 2: SPDocumentLibrary

SharePoint provides a few special subclasses of SPList for specific kinds of lists. These include SPDocumentLibrary, SPPictureLibrary and the essentially obsolete SPIssueList. We can use OfType() to retrieve only lists of a certain type, like this LINQified MSDN sample that enumerates all files in a site collection’s libraries, excluding catalogs and form libraries:

SPSite site = SPContext.Current.Site;
var docs = from web in site.AllWebs.AsSafeEnumerable()
           from lib in web.Lists.OfType<SPDocumentLibrary>()
           from SPListItem doc in lib.Items
           where !lib.IsCatalog && lib.BaseTemplate != SPListTemplateType.XMLForm
           select new { WebTitle = web.Title, ListTitle = lib.Title,
                        ItemTitle = doc.Fields.ContainsField("Title") ? doc.Title : "" };

foreach (var doc in docs)
  Label1.Text += SPEncode.HtmlEncode(doc.WebTitle) + " -- " +
                 SPEncode.HtmlEncode(doc.ListTitle) + " -- " +
                 SPEncode.HtmlEncode(doc.ItemTitle) + "<BR>";

Example 3: SPFieldUser

Finally, let’s pull a list of all user fields attached to lists in the root web. This could also be used to easily find instances of a custom field type.

var userFields = from SPList list in site.RootWeb.Lists
                 from fld in list.Fields.OfType<SPFieldUser>()
                 select new
                 {
                     ListTitle = list.Title,
                     FieldTitle = fld.Title,
                     InternalName = fld.InternalName,
                     PresenceEnabled = fld.Presence
                 };

Contrived examples, perhaps, but potentially useful nonetheless.

Avoiding UserProfile.PersonalSite Leaks

Roger Lamb has posted another edge case in the pursuit of leak-free object model code: UserProfile.PersonalSite. To help follow his best practices, I offer another round of extension methods. First, for UserProfile:

public static void ProcessPersonalSite(this UserProfile profile, Action<SPSite> action)
{
    using (SPSite site = profile.PersonalSite)
    {
        action(site);
    }
}

public static T SelectFromPersonalSite<T>(this UserProfile profile, Func<SPSite, T> selector)
{
    using (SPSite site = profile.PersonalSite)
    {
        return selector(site);
    }
}

Usage:

void PersonalSiteNoLeak()
{
    // open a site collection
    using (SPSite siteCollection = new SPSite("http://moss"))
    {
        UserProfileManager profileManager = new UserProfileManager(ServerContext.GetContext(siteCollection));
        UserProfile profile = profileManager.GetUserProfile("domain\\username");
        profile.ProcessPersonalSite(personalSite =>
        {
            // Process personalSite
        });
    }
}

int CountContextPersonalSiteWebs()
{
    UserProfile myProfile = ProfileLoader.GetProfileLoader().GetUserProfile();
    return myProfile.SelectFromPersonalSite(personalSite =>
    {
        return personalSite.AllWebs.Count;
    });
}

I’ve also encapsulated the verification logic for accessing a MySite web part’s PersonalSite, with variations for projection and with/without exceptions:

public static void ProcessPersonalSite(this WebPart webpart, Action<SPSite> action)
{
    IPersonalPage personalPage = webpart.Page as IPersonalPage;
    if (personalPage == null)
        throw new SPException("Unable to access personal site. Invalid page.");
    if (personalPage.IsProfileError)
        throw new SPException("Unable to access personal site because of a profile error.");

    action(personalPage.PersonalSite);
}

public static T SelectFromPersonalSite<T>(this WebPart webpart, Func<SPSite, T> selector)
{
    IPersonalPage personalPage = webpart.Page as IPersonalPage;
    if (personalPage == null)
        throw new SPException("Unable to access personal site. Invalid page.");
    if (personalPage.IsProfileError)
        throw new SPException("Unable to access personal site because of a profile error.");

    return selector(personalPage.PersonalSite);
}

public static bool TryProcessPersonalSite(this WebPart webpart, Action<SPSite> action)
{
    IPersonalPage personalPage = webpart.Page as IPersonalPage;
    if (personalPage == null || personalPage.IsProfileError)
        return false;

    action(personalPage.PersonalSite);
    return true;
}

public static bool TrySelectFromPersonalSite<T>(this WebPart webpart, Func<SPSite, T> selector, out T value)
{
    value = default(T);
    IPersonalPage personalPage = webpart.Page as IPersonalPage;
    if (personalPage == null || personalPage.IsProfileError)
        return false;

    value = selector(personalPage.PersonalSite);
    return true;
}

Usage:

protected override void CreateChildControls()
{
    base.CreateChildControls();

    this.ProcessPersonalSite(personalSite =>
    {
        // Process personalSite
    });
}

As always, feedback is encouraged.