我有一个包含多个WCF服务的程序集,每个服务都有自己的合同。这一切都很好。该服务的app.config中的服务配置如下所示:

<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?

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

有帮助吗?

解决方案

您可以将所有合同合并到一个类中,因此每个合同都有一个带有baseaddress和一个(或多个)端点的服务。

为避免使用一个大型类文件,您可以使用partial-keyword(假设您使用c#)将类拆分为多个文件。每个文件都可以实现一个契约,这使得维护各个界面变得更加容易。

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

您的配置如下所示:

<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>

其他提示

服务可以共享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 <!>”;目前。做那些独特的,你应该没事。

现在,我必须问一下,你确定你不是只想让这些服务共享命名空间而不是基地址吗?

如果使用自定义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" %>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top