Thursday, August 30, 2012

Integrating Autofac to IIS hosted WCF service application

In this post I'm going to describe the way I've integrated Autofac into my WCF IIS hosted service. While the process is thought to be quite common I've found few interesting aspects there.

First steps could be found at Autofac wikiAt the global application startup one should register the service and set the AutofacHostFactory.Container property. But where is the global application startup in case of WCF service hosted on IIS? Basically we have 3 ways to goI think the most natural for WCF is to create custom ServiceHostFactory where we can register our services.

The next step of integration process is to specify Autofac.Integration.Wcf.AutofacServiceHostFactory as  a factory in our service's svc file. But we've already decided to use our own factory. So we have to dig into autofac sources to try to combine these two factories. Here is the code I've ended up with:

namespace VX.Service
{
    public class ServiceHostFactory : AutofacHostFactory
    {
        public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<VocabExtService>();
            Container = builder.Build();

            return base.CreateServiceHost(constructorString, baseAddresses);
        }

        protected override ServiceHost CreateSingletonServiceHost(object singletonInstance, Uri[] baseAddresses)
        {
            if (singletonInstance == null)
            {
                throw new ArgumentNullException("singletonInstance");
            }
            if (baseAddresses == null)
            {
                throw new ArgumentNullException("baseAddresses");
            }
            return new ServiceHost(singletonInstance, baseAddresses);
        }
    }
}


As you can see I've inherited my factory from AutofacHostFactory and overrided a couple of methods. In CreateServiceHost method I register my service, the second method is left untouched.

The last thing you need to do is to specify the factory at the *.svc file markup. For example:

<%@ ServiceHost Language="C#" Debug="true" Service="VX.Service.VocabExtService, VX.Service" CodeBehind="VocabExtService.svc.cs" Factory="VX.Service.ServiceHostFactory, VX.Service"%>
Pay attention to Service attribute here. I have to change the default one to full name to make AutofacHostFactory work. That's it, you can access the service and use dependency injections in your code.