views:

151

answers:

2

I'm having trouble injecting services dependencies into my WCF service using Autofac 1.4.5. I've read and followed the Autofac wiki page on WcfIntegration but my debugging shows me that my WCF service is created by the System.ServiceModel.Dispatcher.InstanceBehavior.GetInstance() method and not by the AutofacWebServiceHostFactory. What am I doing wrong?

I've set up my ajax.svc file to look like the one in the example for use with WebHttpBinding:

<%@ ServiceHost Language="C#" Debug="true"
    Service="Generic.Frontend.Web.Ajax, Generic.Frontend.Web"
    Factory="Autofac.Integration.Wcf.AutofacWebServiceHostFactory,
             Autofac.Integration.Wcf" %>

My WCF service class Ajax is defined like this:

namespace Generic.Frontend.Web
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(
        RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Ajax
    {
        public MapWebService MapWebService { get; set;}

        public Ajax() {
            // this constructor is being called
        }

        public Ajax(MapWebService mapWebService)
        {
            // this constructor should be called
            MapWebService = mapWebService;
        }

        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        [OperationContract(Name = "mapchange")]
        public MapChangeResult ProcessMapChange(string args)
        {
            // use the injected service here
            var result = MapWebService.ProcessMapChange(args);
            return result;
        }
    }
}

Now I've used the wiring up in the Global.asax.cs as shown in the wiki mentioned above:

var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacModuleWebservice());
var container = builder.Build();
AutofacServiceHostFactory.Container = container;

with

class AutofacModuleWebservice : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.Register<Ajax>();
        builder.Register<MapWebService>().ContainerScoped();
    }
}

In my web.config I have

<services>
    <service name="Generic.Frontend.Web.Ajax">
        <endpoint address="http://mysite.com/ajax.svc/" binding="webHttpBinding"
                  contract="Generic.Frontend.Web.Ajax" />
    </service>
</services>

.

The service already works fine but I can't get the Autofac bits (read: creation/injection) to work. Any ideas?

Edit: Removing the default constructor unfortunately leads to the following exception:

System.InvalidOperationException:
The service type provided could not be loaded as a service because it does not
have a default (parameter-less) constructor. To fix the problem, add a default
constructor to the type, or pass an instance of the type to the host.

Cheers, Oliver

A: 

Try deleting the default Ajax constructor and modifying your constructor to this. If it gets run with mapWebService == null that would indicate a resolution problem.

    public Ajax(MapWebService mapWebService = null)
    {
        // this constructor should be called
        MapWebService = mapWebService;
    }
Igor Zevaka
Thanks for the hint, but I had actually already tried that to the effect of receiving the following System.InvalidOperationException: The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host. That's how I figured that Autofac was actually not creating the service instance.
Oliver
A: 

Is your service setup with InstanceContextMode.Single? If it is then wcf will create your service using the default constructor. To get around this change your instance context mode and let autofac manage the lifetime of your service.

Jon
Hi Jon, no it's not setup with InstanceContextMode.Single. I also tried setting it to PerSession explicitely - to no effect.
Oliver