WCF:是否可以将所有服务设置移到配置文件之外和代码中?

时间:2010-06-18 17:34:16

标签: .net wcf .net-3.5

我有一个现在正在使用一年多的WCF,由其他人编码,我正在尝试重构它,但文件夹结构的组织方式和包含这些方法的svc.cs文件不是我的我习惯从WCF样本I completed

这是我想要实现的目标。由于去年没有任何设置发生变化,我被要求在代码中硬编码所有服务的设置。该服务托管在大型和现有Web应用程序中(我必须将其留在那里),svc文件包含客户端调用的方法,并且此svc.cs文件不位于虚拟目录的根目录但是更深层,让我们说<virtualDirectory>/WebServices/PotatoWebService/PotatoWebService.svc,确实没有在虚拟目录根目录中导致任何问题吗?

由于我正在将配置移出配置文件,我现在正在创建服务,主机,端点,绑定到Web应用程序的global.axax.cs文件中ApplicationStart(),这是正确的地方在Web应用程序中启动此服务?

是否可以在代码中移动所有内容,而不仅仅是endPoint,还可以移动web.config文件中的行为,服务和system.ServiceModel的整个内容,以“清理”配置文件,并停止使用他们不需要的设置吓跑支持和配置管理器?

如果是的话,我已经尝试了2天才能让这个工作没有成功。我现在根据netstat得到的是一个服务启动并运行但是当我在浏览器中打开我的svc文件时,一个异常弹出说服务dosent定义了任何端点,尽管根据nstat我运行的服务:

netstat -a | find LISTENING

...
  TCP    machineName:8097      elamontagne.potato.com:0  LISTENING
...

所以我有一个服务正在运行,但svc文件不知道它并且无法使用它的端点,客户端试图联系服务而无法找到它因为服务没有端点,任何提示都要缩小关于这个问题,有关解决这种情况的提示吗?

     //Address
    string hostingAddress = "PotatoVirtualDirectory/PotatoService/PotatoService.svc";   
    // Binding
    BasicHttpBinding PotatoServiceBinding = ConfigurePotatoServiceBinding(serviceSecurityMode);
    // Contract
    Type PotatoContract = typeof(IPotatoService);
    // Host
    this.PotatoServiceHost = new ServiceHost(typeof(PotatoService), new Uri("http://localhost:8097"));
    // Endpoint
    this.PotatoServiceHost.AddServiceEndpoint(PotatoContract, PotatoBinding, hostingAddress);
    // Behavior
    ConfigurePotatoServiceBehavior(this.PotatoServiceHost, PotatoServiceBinding);
    // Name
    this.PotatoServiceHost.Description.Name = "PotatoNamespace.PotatoService";
    //Start!
    this.PotatoServiceHost.Open();

这个编译并运行,它为我提供了一个处于打开状态的运行服务。客户端无法在通常的位置找到它,并且svc文件抱怨它在web.config中没有任何内容并且想要一个端点ServiceHasZeroAppEndpoints:“服务没有应用程序(非基础架构)端点”

我在调试中逐步完成代码,所有看起来都很好,服务是开放的,我缺少什么,有什么提示可以缩小这个问题?

编辑:从服务主机工厂派生工作顺利,谢谢!

3 个答案:

答案 0 :(得分:2)

您可以编写custom service host factory,您可以在其中以编程方式配置服务,而不是使用配置文件。然后在.svc标记文件中配置此自定义工厂:

<%@ServiceHost Factory="CustomFactory" Service="MyService" %>

答案 1 :(得分:1)

  在ApplicationStart()的

就是这样的   正确的地方开始这项服务   在Web应用程序中?

没有。您不能同时拥有ASP.NET运行时托管和通过代码显式托管。但是你可以像Darin所描述的那样声明一个自定义服务工厂。

  

确实没有在虚拟目录根目录中导致任何问题吗?

这没问题。

另外,请问为什么要以编程方式执行此操作?编写和测试所有代码是不是很痛苦?如果您不喜欢Web.config文件中的大块WCF配置,可以将WCF配置放入单独的配置文件中。

通常,WCF服务的配置方式始终相同。无论是自托管还是IIS托管都没有区别。 ServiceHost具有默认实现方式,即如何构造服务描述和结束点。默认情况下,它将尝试在应用程序配置文件中找到服务配置。在你的情况下,Web.config。使用过的ServiceHost在自托管和IIS托管中完全相同。

不同之处在于此ServiceHost是如何实现的。在自托管中,您可以完全控制,因为您必须自己创建ServiceHost实例。在IIS托管方案中,ASP.NET运行时将使用ServiceHostFactory来实例化您的服务主机。

因此,如果您想手动配置ServiceHost,则必须创建自己的ServiceHostFactory并在SVC文件中引用它。

回到你的问题:

  

如果我理解正确,使用web.config中的设置会自动在iis进程中的aspnet_wp.exe中托管服务

“托管”只是意味着它在Web应用程序中运行。只要将服务部署为Web应用程序的一部分,它就始终由IIS托管。无论您如何以及在何处配置它,都没有其他独立的可执行文件,

  

并在客户端调用.svc文件时自动启动?

在ASP.NET Web应用程序中,所有请求的HTTP都通过ASP.NET“管道”。管道有一组处理程序,可以拾取和处理请求。对于WCF,这是System.ServiceModel.Activation.HttpHandler。这个稍微简化的处理程序将检查它是否具有有效的ServiceHost,如果没有使用ServiceHostFactory创建一个。处理程序绝对不关心你是否已经在Global.asax中创建了一个ServiceHost。

  
    

如果我从global.axax.cs开始使用我的ServiceHost.Open(),那么它会明确地启动它,而不是由iis托管。

  

没有。您在Web应用程序中运行的任何代码都在IIS托管的应用程序域中运行。

  
    

,或者仍由IIS托管,但忽略了svc文件?

  

是的。但更多的是另一种方式。您的Global.asax代码将被忽略,WCF激活仍会尝试创建另一个服务主机。

  
    

然后在这里建议第3个选项,从主机工厂派生的类将从svc调用,服务将以与web.config中的设置相同的方式启动?

  

这是唯一的选择。抓住RedGates Reflector(它是免费的)并反汇编ServiceHostFactory类。它相当小。你会发现你几乎可以从那里的Global.asax复制你的代码并且你已经完成了。 ......当然也应该有大量的文件......

希望有所帮助!

答案 2 :(得分:0)

听起来你可以使用以下方法。

您可以从Web配置中引用自己的配置文件。 为了让这个想法更进一步,请看看Managing ASP.NET Development, Staging and Production Connection Strings (without pulling your hair out)

<configuration>
    <appSettings>
        <add key="ServerConfigPath" value="~/ServerConfig.config"/>
    </appSettings>
</configuration>