All Posts

End to End WebApi Configuration, Part 1: StructureMap

At uShip we’re slowly migrating to a microservice architecture from our existing massive monolith which consists of a large legacy Web Forms project, a Web Api project, and an MVC project. This has a lot of benefits, one of which is that we get to take the lessons we learned setting up the monolith and apply them to all new services we spin up. I recently spent some time setting up an instance of WebApi for my team.

The two areas where I spent the most time working on configuration where the dependency injection framework and data access.  For dependency injection we chose to use Structuremap but the general methodology fits most DI frameworks. For data access we chose NHibernate.

Dependency Injection

Criteria of success:

Before discussing how to set up things up, let’s define what a “good” configuration for our dependency injection looks like. In addition to the obvious criteria of “successfully builds objects for me”, I went in with the following requirements.

  1. When appropriate, dependencies should be automatically disposed at the end of each request.
  2. When appropriate, a single dependency instance should be shared by all of a Controller’s other dependencies. E.g., NHibernate’s ISession;  more on this in part 2)
  3. Dependency instances with explicit state (e.g., a Builder-pattern instance) must never be shared.
  4. Disposal should NOT be tied to .NET’s HttpContext. Doing this means that any application code written with that assumption will not work without an HttpContext meaning it cannot easily be reused in other contexts which do not have an HttpRequest (e.g. Scheduler, Message Queue Subscribers).
  5. Disposal of broadly scoped dependencies (per request or per application) should be handled by the framework whenever possible.

 

What we do in the monolith:

In our monolith we originally used the HttpContext lifecycle, but we ended up having the issue described in #3 above. To fix this we switched to the HybridHttpThreadOrThreadLocalScoped Lifecycle. This lifecycle will use the HttpContext if it is present, otherwise it will fall back to treating each thread in the same way it would treat each HTTP request. This was a decent solution but required all non-HTTP workers to be explicitly threaded. Overall, both of these lifecycles are frowned upon by  StuctureMap’s developers. Instead they recommend the use of NestedContainers. If you are unfamiliar with with nested containers they are ” a mechanism for service resolution and clean object disposal in the context of short lived operations” (e.g. HTTP requests).

Dependency Injection Implementation using StructureMap:

Initially I hoped that an open source solution would fulfill my needs.  I installed the WebApi.Contrib.Ioc.Structurmap nuget package and started testing. While this nuget uses NestedContainers, it sadly never disposes of them. I forked their repository as a starting point and began modifying it to fix the disposal issue.

Dependency Injection in WebApi (and MVC) typically starts at controller construction. In both cases there are two easy extension points that allow us the specify how our controllers are built. The first extension point is the IDependencyResolver which in turn returns an IDependencyScope. The second extension point is the IHttpControllerActivator.

Let’s look at the DependencyResolver first; the DependencyResolver by WebApi in two locations the ModelBinderAttribute and the DefaultHttpControllerActivator. Let’s ignore the ModelBinderAttribute for now. The DefaultHttpControllerActivator calls the GetDependencyScope extension method on the request, creating a scope if one has not already been created, registers the scope to be disposed at the end of the request, and then creates the controller from the scope.

The relevant method in the DefaultHttpControllerActivator is provided for context:

 //From System.Web.Http.Dispatcher
 private static IHttpController GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, out Func activator)
        {
            Contract.Assert(request != null);
            Contract.Assert(controllerType != null);

            // If dependency resolver returns controller object then use it.
            IHttpController instance = (IHttpController)request.GetDependencyScope().GetService(controllerType);
            if (instance != null)
            {
                activator = null;
                return instance;
            }

            // Otherwise create a delegate for creating a new instance of the type
            activator = TypeActivator.Create(controllerType);
            return null;
        }

You can refer to my fork for a StructureMap implementation of the Resolver and Scope

You can additionally override the DefaultHttpControllerActivator with your own implementation of IControllerActivator.  You should only do this if you need the additional context of the Request to construct your controller. If you chose to do this you should keep in mind that the default activator does a lot of the heavy lifting that you will lose and need to re-implement (validation, caching, thread safety, etc). Additionally your need to register your nested container for disposal yourself either with the RegisterForDisposal extension method or by calling GetDependencyScope and retrieving the NestedContainer from the scope. This is where the StructureMapContrib nuget goes awry, they use both the Resolver and the Activator but do not register the nested container for disposal.  A simple implementation without caching looks like this:

public class StructureMapControllerActivator : IHttpControllerActivator
    {
        public IHttpController Create(
           HttpRequestMessage request,
           HttpControllerDescriptor controllerDescriptor,
           Type controllerType)
        {
            var scope = request.GetDependencyScope();
            // GetService calls IContainer.GetInstance<>(); 
            // Container.GetInstance returns itself.
            var container = (IContainer)scope.GetService(typeof(IContainer));
            //Do something with the container that needs the request or descriptor
            return GetControllerFromContainer(container, controllerType);
        }

        private IHttpController GetControllerFromContainer(IContainer container, Type type)
        {
            IHttpController controller;
            // TryGetInstance does not return contcete types, 
            // ApiControllers are routinely registered without interfaces
            try
            {
                controller = container.GetInstance(type) as IHttpController;
            }
            catch (StructureMapException exe)
            {
                return null;
            }
            return controller;
        }
    }

Finally, whichever path you choose you must register your chosen implementation in the global.asax:

    public class WebApiApplication : HttpApplication
    {
        public static IContainer Container { get; private set; }

        protected void Application_Start()
        {
            Container = new Container();
            Container.Configure(x =>
            {
                //Register Dependencies
                //Optionally Register IControllerActivator
                //For<IControllerActivator>.Use<StructureMapControllerActivator>();
            });
            GlobalConfiguration.Configure(WebApiConfig.Register);
            GlobalConfiguration.Configuration.DependencyResolver = new StructureMapResolver(Container)
        }

        protected void Application_End()
        {
            //Dispose of containers to make sure Singleton Scoped dependencies get disposed 
            Container.Dispose();
        }
    }

Because I don’t need the additional control given by the IControllerActivator I chose to use the Resolver/Scope pair.

Let’s review our success criteria to make sure this meets all of them.

  1. Per request disposal: The dependency scope is registered for disposal when it is created. Per StructureMap’s behavior Transient Dependencies are disposed with the nested container (Note: AlwaysUnique and Singletons will not be disposed.)
  2. Ability to have one instance of a dependency per request: All Transient dependencies will only be created once per controller.
  3. Ability to have stateful dependencies that won’t be share: The AlwaysUnique lifecycle handles this case
  4. No dependency on HttpContext: Nested Containers handle this.
  5. Automatic Disposal: All code written to run within a controller will handle this. Code written to run in Filters and Handlers will also be automatic if you retrieve the dependency from the scope.

And there we have it, a basic summary of how dependency injection in WebApi. Whether you choose to roll your own or use one of the many existing open source solutions this should help you understand the building blocks.

If you would like to play with it yourself I have a github with a fully configured WebApi here.

In part 2 of this blog I will discuss how NHibernate fits into this picture and how we are managing per request transactions.

[amp-cta id=’8486′]