Johan Johan - 3 months ago 18
reST (reStructuredText) Question

How do I host a rest service with autofac and wcf?

Following this guide I managed to get a service working over iis with was.
https://code.google.com/p/autofac/wiki/WcfIntegration#Self-Hosted_Services

However, I also need it host a rest service. I could actually live with only rest.

But with the documentation available I have not been successful yet.

Does anyone have a good guide for getting it working with rest service with wcf(was)+autofac?

I do not seem to get the endpoint right, no endpoint at all actually.

My code, where did I miss something?

namespace WcfServiceHost.Infrastructure
{
public class AutofacContainerBuilder
{

public static IContainer BuildContainer()
{
var builder = new ContainerBuilder();
builder.RegisterType<LoginFactory>().As<ILoginFactory>();
builder.RegisterType<SupplierHandler>().As<ISupplierHandler>();
builder.RegisterType<UserHandler>().As<IUserHandler>();
builder.RegisterType<SupplierRepository>().As<ISupplierRepository>();
builder.RegisterType<TidsamProductSupplierProxy>().As<ILogin>();

builder.RegisterType<StoreService>().As<IStoreService>();
//builder.RegisterType<StoreService>();

return builder.Build();
}
}
}



<%@ ServiceHost Language="C#" Debug="true"
Service="Services.IStoreService, Services"
Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf"
%>



namespace WcfServiceHost.App_Code
// ReSharper restore CheckNamespace
{
public static class AppStart
{
public static void AppInitialize()
{
// Put your container initialization here.
// build and set container in application start
IContainer container = AutofacContainerBuilder.BuildContainer();
AutofacHostFactory.Container = container;

// AutofacWebServiceHostFactory AutofacServiceHostFactory
RouteTable.Routes.Add(new ServiceRoute("StoreService", new RestServiceHostFactory<IStoreService>(), typeof(StoreService)));

}
}
}



public class RestServiceHostFactory<TServiceContract> : AutofacWebServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
var webBehavior = new WebHttpBehavior
{
AutomaticFormatSelectionEnabled = true,
HelpEnabled = true,
FaultExceptionEnabled = true
};
var endpoint = host.AddServiceEndpoint(typeof(TServiceContract), new WebHttpBinding(), "Rest");
endpoint.Behaviors.Add(new WebHttpBehavior { HelpEnabled = true });
endpoint.Name = "rest";
endpoint.Behaviors.Add(webBehavior);

return host;
}

}


config:

<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<serviceActivations>
<add factory="Autofac.Integration.Wcf.AutofacServiceHostFactory"
relativeAddress="~/StoreService.svc"
service="Services.StoreService" />
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
<handlers>
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" />
</handlers>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>

</configuration>


Then I do get an endpoint. But as soon as I change to AutofacWebServiceHostFactory I get no endpoint and no rest/help. However, I can query the rest services in IStoreService.

Answer

To solve this. I removed the reference to the autofac AutofacServiceHostFactory in the config. Then I wrote endpoints manually with behaviors.

I used AutofacServiceHostFactory in the .svc file for the service.

This was not the way I'd prefer to do it but otherwise I didn't both the rest endpoint and the basichttp soap endpoint to work.

If someone has a better solution, I'll give you the answer.


@John Meyer Upon request for my code sample, I managed to find some old code.

The service like EmailService.svc in my folder Services, edit like so:

<%@ ServiceHost Language="C#" Debug="true" 
Service="Services.IEmailService, Services" 
Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf"
 %>

in web.config

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
    <assemblyIdentity name="Autofac" publicKeyToken="x" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
  </dependentAssembly>
  <dependentAssembly>

AppStart class

public static class AppStart
{
    public static void AppInitialize()
    {
        IContainer container = AutofacContainerBuilder.BuildContainer();
        AutofacHostFactory.Container = container;}
}
...

I seperated the container to another class. Dont forget the correct using using Autofac;

and the method in the class to set up the container

public static IContainer BuildContainer()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<EmailService>().As<IEmailService>();
            return builder.Build();
        }
Comments