如何使用autofac和wcf托管休息服务?

时间:2013-10-08 14:36:13

标签: wcf rest autofac

按照本指南,我设法通过iis在iis上运行服务。 https://code.google.com/p/autofac/wiki/WcfIntegration#Self-Hosted_Services

但是,我还需要它提供休息服务。我实际上只能休息。

但是有了可用的文档,我还没有成功。

有没有人有一个很好的指导,让它使用wcf(was)+ autofac进行休息服务?

我似乎没有让端点正确,实际上根本没有端点。

我的代码,我在哪里错过了什么?

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>

然后我得到一个端点。但是一旦我改为AutofacWebServiceHostFactory,我就没有端点,也没有休息/帮助。但是,我可以在IStoreService中查询其余服务。

2 个答案:

答案 0 :(得分:0)

REST WCF服务的注册几乎与注册非REST WCF服务类似。只更改了一些内容:绑定,端点和服务合同。

使用WCF REST服务(非常简化)的autofac wiki中的修改示例。

作为依赖项的记录器的接口和实现。

public interface ILogger
{
    void Write(string message);
}

public class Logger : ILogger
{
    public void Write(string message)
    {
        Console.WriteLine(message);
    }
}

其余wcf服务的合同和实施。

[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;
    }
}

用于构建容器和托管Web服务的控制台应用程序代码。

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);
        }
    }
}

要进行测试,请运行任何浏览器并打开网址http://localhost:8080/EchoService/Echo/test_test

答案 1 :(得分:0)

解决这个问题。我在配置中删除了对autofac AutofacServiceHostFactory的引用。然后我用行为手动编写了端点。

我在服务的.svc文件中使用了AutofacServiceHostFactory。

这不是我喜欢这样做的方式,但除此之外我没有其他端点和basichttp soap端点都能正常工作。

如果有人有更好的解决方案,我会给你答案。


@John Meyer 根据我的代码示例请求,我设法找到了一些旧代码。

像我的文件夹服务中的EmailService.svc这样的服务,编辑如下:

<%@ ServiceHost Language="C#" Debug="true" 
Service="Services.IEmailService, Services" 
Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf"
 %>
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类

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

我将容器分隔到另一个班级。 别忘了正确使用     使用Autofac;

和类中设置容器的方法

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