Wednesday, March 27, 2013

Annotation-based Documentation Provider for APIExplorer

The APIExplorer is a nice way to automatically build a docs page for your WebAPI RESTful services. The documentation is created using reflection and then the IDocumentationProvider tries to find the textual information about your methods and method parameters.

The problem is that the reference implementation shows how the docs could be retrieved from the XML documentation generated during the compilation of a service. If this is not an option for you, you could use this simple provider which uses System.ComponentModel.DataAnnotations.Display attributes for method decoration:

public class AttributeDocumentationProvider : IDocumentationProvider
 {
     #region IDocumentationProvider Members
 
     public string GetDocumentation( HttpParameterDescriptor parameterDescriptor )
     {
         ReflectedHttpParameterDescriptor reflectedParameterDescriptor = 
             parameterDescriptor as ReflectedHttpParameterDescriptor;
         if ( reflectedParameterDescriptor != null )
         {
             var display = reflectedParameterDescriptor.ParameterInfo
                 .GetCustomAttributes( typeof( DisplayAttribute ), false )
                 .OfType<DisplayAttribute>().FirstOrDefault();
             if ( display != null )
                 return display.Description;
             else
                 return reflectedParameterDescriptor.ParameterInfo.Name;
         }
 
         return string.Empty;
     }
 
     public string GetDocumentation( HttpActionDescriptor actionDescriptor )
     {
         ReflectedHttpActionDescriptor reflectedActionDescriptor = 
             actionDescriptor as ReflectedHttpActionDescriptor;
         if ( reflectedActionDescriptor != null )
         {
             var display = reflectedActionDescriptor.MethodInfo
                 .GetCustomAttributes( typeof( DisplayAttribute ), false )
                 .OfType<DisplayAttribute>().FirstOrDefault();
             if ( display != null )
                 return display.Description;
             else
                 return reflectedActionDescriptor.MethodInfo.Name;
         }
 
         return string.Empty;
     }
 
     #endregion
 }

This way the WebAPI controller could be documented as follows:

public class MyWebAPIController : ApiController
{
    /// <summary>
    /// POST/Create a new Foo
    /// </summary>
    [Display( Description="Create a new instance of Foo")]
    public HttpResponseMessage PostFoo( 
        [Display( Description="Name of the newly created Foo")]
        string fooName 
        )
    {
       ...

An advantage of this approach is that the docs are part of the assembly metadata and there is no need for external XML documentation files.

Wednesday, March 20, 2013

Unity and Http Per Request Lifetime Manager

A common requirement for an IoC container is to support different lifetime managers with at least the “transient” and “container controlled” provided out-of-the-box. Unity is no exception and lifetime management works great.

Another, more specific but still common requirement is to have a “per-request” lifetime manager so that the container would resolve the same the instance of your service in a http request scope but different scopes would yield different instances of the service. This way for example, the container could serve database sessions with no risk of unintented concurrency issues.

The small inconvenience of Unity is that the “per request” manager is not provided and you have to bake one on your own. The aim of this post is to warn the reader that although this sounds like an easy task, one can easily find an incorrent implementation and get into trouble.

Let us take these two implementations and compare them:

  1. Using Microsoft Unity in ASP.NET MVC by Brian Mains
  2. Unity and lifetime management by John Bledsoe

First one:

public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
{
    private HttpContextBase _context = null;
    public HttpContextLifetimeManager()
    {
        _context = new HttpContextWrapper(HttpContext.Current);
    }
    public HttpContextLifetimeManager(HttpContextBase context)
    {
        if (context == null)
            throw new ArgumentNullException("context");
        _context = context;
    }
    public void Dispose()
    {
        this.RemoveValue();
    }
    public override object GetValue()
    {
        return _context.Items[typeof(T)];
    }
    public override void RemoveValue()
    {
        _context.Items.Remove(typeof(T));
    }
    public override void SetValue(object newValue)
    {
        _context.Items[typeof(T)] = newValue;
    }
}

The second one:

public class PerRequestLifetimeManager : LifetimeManager
{
    private readonly object key = new object();
 
    public override object GetValue()
    {
        if (HttpContext.Current != null && 
            HttpContext.Current.Items.Contains(key))
            return HttpContext.Current.Items[key];
        else
            return null;
    }
 
    public override void RemoveValue()
    {
        if (HttpContext.Current != null)
            HttpContext.Current.Items.Remove(key);
    }
 
    public override void SetValue(object newValue)
    {
        if (HttpContext.Current != null)
            HttpContext.Current.Items[key] = newValue;
    }
}

Seemingly both are correct as both use the Items container which is request-specific which means that items are stored to and retrieved from the request specific context. So far, so good.

However, there is a fundamental problem in the first implementation. The problem comes from the fact that the lifetime manager has its own lifetime management policy – the manager is created once for a container and registered type.

In a web application, typically you have a single, shared container in the http application scope. Following the Composition Root principle, you initialize the container and your services somewhere early in the application’s life cycle but the container is alive and is reused when there is a need to resolve services in the application scope.

In the first approach, the lifetime manager is initialized once and it always uses the http context of the very first request, storing the context in a private variable and reusing it in subsequent requests. This, of course, is completely against the requirement to always use the current request context!

Lesson learned – pay a close attention to the lifetime management policy and how it is implemented.