服务合同继承后WCF中的合同发现

时间:2010-02-23 15:36:39

标签: c# wcf web-services

旧版本的WCF根据旧版本的界面提供

<endpoint name="ServiceName" address="http://production.server/Service.svc" 
 binding="basicHttpBinding" bindingConfiguration="myBasicHttpBinding" 
 contract="myAPI.IOriginalService" />

新版本发布

<endpoint name="ServiceName" address="http://development.server/Service.svc"
 binding="basicHttpBinding" bindingConfiguration="myBasicHttpBinding" 
 contract="myAPI.IDerivedService" />

这很好用。旧客户端可以通过询问IOriginalService连接到任一服务器,新客户端可以请求IDerivedService ...但是他们只能向开发服务器询问它,如果他们询问生产服务器,则会出错被扔了。那一切都很好。

我宁愿让新客户尝试有点聪明,但他们尽可能使用新格式,但如果不可用则使用旧格式。我可以抓住异常,但这很昂贵而且我宁愿做一个测试,而不是捕捉已知的可能结果。

所以我想连接到端点并询问它的合同值,然后使用返回值来决定要求的类型,例如:

var endPoint = someMethod("ServiceName");
var contractName = endPoint.WhatContractDoYouOffer(); 
if(contractName == "IOriginalService") 
  CallAMethod<IOriginalService>(parameters);
else
  CallAMethod<IDerivedService>(newParameters);

这可行吗?

1 个答案:

答案 0 :(得分:0)

WCF中没有“开箱即用”支持此功能 - 除了可能:

  • 在一个端点上公开您的旧服务合同
  • 在单独的新端点(新地址,新端口 - 无论如何)
  • 上公开新服务

但是做出决定在哪里连接需要在客户端进行。

您可能会想到一个“调度员”WCF服务,您可以询问该去哪个合同 - 但至少这个WCF服务的端点和合同必须始终保持固定。

当然,您可以在客户端app.config中拥有多个端点 - 这些端点可以加载到内存中并进行检查:

ClientSection cs = ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;

if(cs != null)
{
    foreach (ChannelEndpointElement ep in clientSection.Endpoints)
    {
        if(ep.Contract == 'IMyService')
        {
           Uri endpointAddress = e.Address;
        }
    }
} 

有了这个,您可以创建一个包含所有端点的单个客户端配置,并且您可以动态地找到您感兴趣的端点。