简体   繁体   English

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

[英]Contract discovery in WCF after Service Contract Inheritence

The old version of the WCF was delivering according to the old version of the interface WCF的旧版本根据接口的旧版本进行交付

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

with the new version delivering 随着新版本的交付

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

This works fine. 这很好。 The old clients can connect to either server by asking for IOriginalService and new clients can ask for IDerivedService ... but they can only ask the development server for it, if they ask the production server, an error is thrown. 旧客户端可以通过请求IOriginalService来连接到任一服务器,而新客户端可以要求IDerivedService ...,但是它们只能向开发服务器请求,如果他们向生产服务器询问,则会引发错误。 That's all fine. 没事的

I'd prefer to have new clients try to be a bit clever, though and use the new format when they can, but use the old if it isn't available. 我宁愿让新客户尝试变得聪明一点,并在可能的时候使用新格式,但是如果不可用,则使用旧格式。 I could just catch the exception, but that's expensive and I'd much rather do a test, than catch a known likely outcome. 我可以捕捉到异常,但这很昂贵,我宁愿进行测试,也不愿捕捉已知的可能结果。

So I want to connect to the endpoint and ask it for the contract value, then use the return value to decide which type to ask for, eg 因此,我想连接到端点并要求其提供合同价值,然后使用返回值来确定要询问的类型,例如

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

Is this feasible? 这可行吗?

There's nothing within WCF "out of the box" to support this feature - except maybe: WCF中没有“开箱即用”的功能来支持此功能-可能除外:

  • expose your old service contract on one endpoint 在一个端点上公开您的旧服务合同
  • expose the new service on a separate, new endpoint (new address, new port - whatever) 在单独的新端点(新地址,新端口-任何其他位置)上公开新服务

But making that decision where to connect to needs to be made client-side. 但是要在客户端确定连接的位置。

You could potentially think up a "dispatcher" WCF service which you could ask where to go for which contract - but then at least this WCF service's endpoint and contract would have to remain fixed for all times. 您可能会想出一个“调度程序” WCF服务,您可以问该去哪里签约-但至少此WCF服务的终结点和合同必须始终保持固定。

Of course, you can have multiple endpoints in your client-side app.config - and those can be loaded into memory and inspected: 当然,您可以在客户端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;
        }
    }
} 

With this, you could create a single client side config which contains all endpoints, and you can dynamically find the one you're interested in. 这样,您可以创建一个包含所有端点的单个客户端配置,并且可以动态找到您感兴趣的配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM