2009-01-12 122 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" %>