2009-01-12 121 views
11

我有一个包含几个WCF服务的程序集,每个服务都有自己的合同。这一切都很好。在App.config该服务的服务配置是这样的:几个WCF服务可以共享一个公共BaseAddress吗?

<services> 
    <service behaviorConfiguration="WcfService.AlyzaServiceBehavior" 
    name="Sam.Alyza.WcfService.ServiceWebsites"> 
    <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Websites/" /> 
     </baseAddresses> 
    </host> 
    </service> 
    <service behaviorConfiguration="Sam.Alyza.WcfService.LogReaderServiceBehavior" 
    name="Sam.Alyza.WcfService.ServiceLogReader"> 
    <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/LogReader/" /> 
     </baseAddresses> 
    </host> 
    </service> 
    <service behaviorConfiguration="Sam.Alyza.WcfService.ServiceSystemverwaltungBehavior" 
    name="Sam.Alyza.WcfService.ServiceSystemverwaltung"> 
    <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Systemverwaltung/" /> 
     </baseAddresses> 
    </host> 
    </service> 
    [...] 
</services> 

因为我有一记大项目,更多的合同,我希望有一种方法来共享之间的BaseAddress不同的服务合同。
如果这只是一个具有不同契约和端点的服务,我可以设置一个ommon baseaddress,但是如何为多个服务设置一个通用baseaddress?

当然,我需要为客户端类似的东西。

回答

8

您可以在一个类中合并所有合约,因此每个合约您有一个基本地址和一个(或多个)端点的服务。

为了避免有一个大的类文件,你可以使用partial-keyword(假设你使用c#)来将这个类拆分成多个文件。每个文件都可以实现一个合同,这使得维护单个界面变得更加容易。

在C++中,你可以使用#包括或多重继承,但意味着大量的纪律...

你的配置是这样的:

<services> 
    <service behaviorConfiguration="WcfService.AlyzaServiceBehavior" 
    name="Sam.Alyza.WcfService.ServiceAll"> 
    <endpoint address="Websites/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="LogReader/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="Systemverwaltung/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/" /> 
     </baseAddresses> 
    </host> 
    </service> 
</services> 
2

服务可以共享BaseAddress值(包括端口号,如果Net.Tcp端口共享服务正在运行)。这是端点地址必须是唯一的。注意在你的配置文件中,每个ServiceHost的MEX端点都有一个“mex”的地址。您的其他端点具有空字符串的地址。当您为端点提供WCF的相对地址(至少在配置文件中)时,基地址将作为前缀。因此,LogReader服务的MEX端点地址是“net.tcp:// localhost:8731/Design_Time_Addresses/SamAlyza/LogReader/mex”。

由于在主服务端点上没有设置相对地址,因此ServiceHost的基地址被用作主服务端点的实际地址。因为没有两个端点可以有重叠的Uri.AbsolutePath值,所以你的例子会让你相信基地址值不能共享。承载WCF服务的ServiceHost类没有内置端点,而ServiceEndpoint类具有ListenUri属性,该属性将根据您提供的设置进行填充。

如果您将示例中的baseAddress值更改为全部匹配,只要您在Endpoint元素上设置了唯一的相对地址值,则一切都应该起作用。但是,看起来你可能遇到一些MEX端点的挑战,因为它们目前都有地址“mex”。让这些独特,你应该没问题。

现在,我必须问,你确定你不是简单地希望这些服务共享一个名称空间,而不是基地址?

+0

另一点是baseAddress不过是当前的位置,可以这么说。这个想法是所有的端点通常都是相对于baseAddress的。因此,如果您试图跨所有服务共享相同的baseAddress,则会限制您的部署选项。 – 2009-01-12 20:40:16

+0

如果您正在寻找一种简化配置的方法,您将不得不切换到使用代码而不是配置接线。您可以编程方式创建ServiceHost和ServiceEndpoint实例,并可能从数据库中提取Uri.AbsolutPath值。 – 2009-01-12 20:43:02

1

您还可以设置基地如果使用自定义的ServiceHostFactory,则代码中的地址。

在配置你可以有一些应用程序设置:

<configuration> 
    <appSettings> 
    <add key="BaseAddress" value="http://localhost:1234" /> 
    </appSettings> 
<configuration> 

然后创建一个自定义ServiceHostFactory:

public sealed class MyServiceHostFactory : ServiceHostFactory 
{ 
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
    { 
     var baseAddy = ConfigurationManager.AppSettings["BaseAddress"]; 
     baseAddresses.Add(new Uri(baseAddy)); 
     return new ServiceHost(serviceType, baseAddresses); 
    } 

} 

那么你也必须改变你的.svc文件,使用该工厂:

<%@ ServiceHost Language="C#" Debug="true" Service="MyApp.MyService" CodeBehind="MyService.svc.cs" Factory="MyApp.MyServiceHostFactory" %>