Simple WCF. Hosting WCF service by Autofac in ASP.NET MVC 3

By Mirek on (tags: Autofac, IoC, MVC 3, WCF, categories: code)

One of features of Autofac is that it can be used to host a WCF service. I have tried to host a WCF service within an already existing ASP.NET MVC 3 web application. The problem was that the service needed to use some resources which were managed by Autofac and was also used this MVC application. I spend few hours until I figure out what is going on and how to make it work together.

Let’s assume we have a WCF service MyService class which requires some dependencies to work.

   1: [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
   2: [ServiceContract]
   3: public class MyService
   4: {
   5:     private IMyManager myManager;
   7:     public MyService(IMyManager myMan)
   8:     {
   9:         myManager = myMan;
  10:     }
  12:     [OperationContract]
  13:     public string DoAction(string message)
  14:     {
  15:        return myManager.DoSmth...
  16:     }
  17: }

We want to host this service inside ASP.NET MVC 3 web application. The dependency MyManager is also used in that application and consumed during http requests. There can be many examples of such usage, for instance MyManager could be an repository for some business data which can be modified from MVC application and can also be consumed via WCF service. I could of course create an service host manually from the code and use IoC to resolve the instsnce of MyManager, but I prefer a clean solutions.
The first requirement to wcf service be managed by an inversion of control container is that its instance context mode is defined as PerCall (see line 1 in above listing). As Autofac wiki says setting it to Single causes that WCF will attempt to create a singleton instance for you in the constructor of the ServiceHost instance that is created by the base ServiceHostFactory, giving Autofac no chance to affect the instance creation.

The dependency registration would looks like follows

   1: var builder = new ContainerBuilder();
   3: builder.RegisterType<MyManager>().AsImplementedInterfaces().InstancePerLifetimeScope();
   5: builder.RegisterType<MyService>().InstancePerLifetimeScope();
   7: ...
   9: var container = builder.Build();
  11: AutofacHostFactory.Container = container;
  13: DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

Since WCF requests does not have an http context we can not use InstancePerHttpRequest(). Instead we can use InstancePerLifetimeScope() which is resolvable for both WCF and http requests. Autofac Wiki says

The default ASP.NET and WCF integrations are set up so that InstancePerLifetimeScope() will attach a component to the current web request or service method call.

In line 11 we set the AutofacHostFactory which derives from  ServiceHostFactory and is used to create the service instances on requests. We apply this factory in .svc file or in service activator configuration as factory attribute

   1: <serviceHostingEnvironment multipleSiteBindingsEnabled="true">
   2:   <serviceActivations>
   3:     <add service="Company.MyService, Company"
   4:          factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf"
   5:          relativeAddress="MyService.svc" />
   6:   </serviceActivations>
   7: </serviceHostingEnvironment>

And that is generally all what we need to start hosting WCF service in ASP.NET MVC 3 application using Autofac dependency incjector.

When the service is requested the AutofacServiceHostFactory creates the instance of MyManager, then inject it in and creates the instance of MyService.