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.
A registration of REST WCF service is almost similar to registration non-REST WCF service. Only changed a few things: bindings, endpoints and service contract.
The interface and implementation for the logger that will be the dependency.
public interface ILogger
{
void Write(string message);
}
public class Logger : ILogger
{
public void Write(string message)
{
Console.WriteLine(message);
}
}
The contract and implementation for the rest wcf service.
[ServiceContract]
public interface IEchoService
{
[OperationContract]
[WebGet(UriTemplate = "/Echo/{message}")]
string RestEcho(string message);
}
public class EchoService : IEchoService
{
private readonly ILogger _logger;
public EchoService(ILogger logger)
{
_logger = logger;
}
public string RestEcho(string message)
{
_logger.Write(message);
return message;
}
}
The Console Application code for building the container and hosting the web service.
class Program
{
static void Main()
{
ContainerBuilder builder = new ContainerBuilder();
builder.Register(c => new Logger()).As<ILogger>();
builder.Register(c => new EchoService(c.Resolve<ILogger>())).As<IEchoService>();
using (IContainer container = builder.Build())
{
Uri address = new Uri("http://localhost:8080/EchoService");
ServiceHost host = new ServiceHost(typeof(EchoService), address);
var binding = new WebHttpBinding();
var endpointAddress = new EndpointAddress(address);
var description = ContractDescription.GetContract(typeof(IEchoService));
var endpoint = new ServiceEndpoint(description, binding, endpointAddress);
endpoint.Behaviors.Add(new WebHttpBehavior { HelpEnabled = true });
host.AddServiceEndpoint(endpoint);
host.AddDependencyInjectionBehavior<IEchoService>(container);
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true, HttpGetUrl = address });
host.Open();
Console.WriteLine("The host has been opened.");
Console.ReadLine();
host.Close();
Environment.Exit(0);
}
}
}
For testing, run any browser and open a url http://localhost:8080/EchoService/Echo/test_test
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();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.