http://blogs.clariusconsulting.net/kzu

Daniel Cazzulino's Blog

Go Back to
kzu′s Latest post

How to use Autofac with WCF Web API

The new configuration model in the latest WCF Web APIs allows extending the service instantiation via what is called a resource factory.

For Autofac, I wanted to support a per-request lifetime scope, so I used the concept of instance context extensions in the Web APIs to place our scope so that it can be disposed on release.

public class AutofacResourceFactory : IResourceFactory
{
    private IContainer container;

    public AutofacResourceFactory(IContainer container)
    {
        this.container = container;
    }

    public object GetInstance(Type serviceType, InstanceContext instanceContext, HttpRequestMessage request)
    {
        // Begin lifetime scope when the service is instantiated.
        var lifetime = this.container.BeginLifetimeScope();
        // Hold the lifetime as an extension in the instance context
        instanceContext.Extensions.Add(new AutofactLifetimeExtension(lifetime));

        return lifetime.Resolve(serviceType);
    }

    public void ReleaseInstance(System.ServiceModel.InstanceContext instanceContext, object service)
    {
        var extension = instanceContext.Extensions.OfType<AutofactLifetimeExtension>().FirstOrDefault();
        // If we find our extension there, dispose it so the lifetime gets disposed.
        if (extension != null)
            extension.Dispose();
    }

    private class AutofactLifetimeExtension : IExtension<InstanceContext>, IDisposable
    {
        private ILifetimeScope lifetime;
        private bool isDisposed;

        public AutofactLifetimeExtension(ILifetimeScope lifetime)
        {
            this.lifetime = lifetime;
        }

        public void Attach(InstanceContext owner)
        {
        }

        public void Detach(InstanceContext owner)
        {
            Dispose();
        }

        public void Dispose()
        {
            if (this.isDisposed)
                return;

            this.lifetime.Dispose();
            this.isDisposed = true;
        }
    }
}

Configuring the factory is straightforward:

IContainer container = BuildContainer();
var config = HttpHostConfiguration.Create()
    .SetResourceFactory(new AutofacResourceFactory(container));

routes.MapServiceRoute<FooResource>("foo", config);

Pretty sleek! WCF is looking like a usable technology now… Smile

Comments

4 Comments

  1. Sweet! That almost seems to easy. A nice change for WCF indeed.

  2. Brilliant!! Especially that lifetime part.

  3. Typo? Autofac[t]LifetimeExtension

  4. Is there anything equivalent for Message/operation Factories?
    Can we use same IoC to generate/resolve dependencies for Service/Resource, Message and Operation?
    somenthing like
    IContainer container = BuildContainer();
    var config = HttpHostConfiguration.Create()
    .SetResourceFactory(new AutofacResourceFactory(container))
    .SetMessageHandlerFactory( new AutofacMessageFactory(container)))

    routes.MapServiceRoute(“foo”, config);