简体   繁体   English

仅为WCF服务上可用的服务合同接口之一生成客户端

[英]Generate client for only one of the Service Contract interfaces available on a WCF service

I am currently refactoring a large WCF service which consisted of one service contract interface ("SCI" from here on) used by multiple different client applications. 我目前正在重构一个大型的WCF服务,该服务由多个不同的客户端应用程序使用的一个服务合同接口(此后称为“ SCI”)组成。 I have split up the SCI so that for each type of client application there is an SCI specific to the operations it requires. 我对SCI进行了拆分,以便对于每种类型的客户端应用程序都有一个特定于其所需操作的SCI。 Some shared sections of the SCI's are defined in a base SCI, which the client application specific SCI's inherit. SCI的某些共享部分在基本SCI中定义,客户端应用程序特定的SCI继承该基本SCI。

There is a single service class that implements all the client specific SCI's. 有一个服务类可以实现所有客户端特定的SCI。 The fact that there is a diamond interface inheritance situation from the shared base SCI means, sometimes, that the same operation is available through multiple SCI's. 共享基础SCI存在菱形接口继承情况的事实有时表示可以通过多个SCI进行相同的操作。 When auto-generating clients (especially with async client methods), the resultant code has many ugly <generated-type>1,2,3 etc... 自动生成客户端时(尤其是异步客户端方法),生成的代码具有许多难看的<generated-type>1,2,3等。

In order to avoid this, I would like to add a service reference to each of the client applications that only generates a client for the SCI relevant to that particular application. 为了避免这种情况,我想向每个客户端应用程序添加服务引用,该服务引用仅为与该特定应用程序相关的SCI生成客户端。 This should result in no problems due to the same function appearing on different SCI's. 由于相同的功能出现在不同的SCI上,因此不会出现任何问题。

Is this possible? 这可能吗?

Any other tips on achieving both modularity and code-reuse in this situation would also be appreciated. 在这种情况下实现模块化和代码重用的任何其他技巧也将受到赞赏。

What you want to do is to create a service contract interface (you can manually do this, pull it from the original service implementation or auto generate it then copy it out). 您要做的是创建一个服务合同接口(您可以手动执行此操作,将其从原始服务实现中拉出或自动生成,然后将其复制出来)。

Then instead of using a service reference use the channel factory to bind to your service (as below). 然后,不要使用服务引用,而使用通道工厂绑定到您的服务(如下所示)。 This is a way nicer way of referencing WCF services. 这是引用WCF服务的更好的方法。

You need the following refs to do this: 您需要以下引用来执行此操作:

using System.ServiceModel;
using System.ServiceModel.Description;

Then you can use the following: 然后,您可以使用以下命令:

     var binding = new WebHttpBinding();
     var factory = new ChannelFactory<IMyServiceContract>(binding, new EndpointAddress("http://url:port"));
     factory.Endpoint.Behaviors.Add(new WebHttpBehavior());

     var myService = factory.CreateChannel();

     myService.ServiceMethod();

Luke's suggestion worth to try. 卢克的建议值得尝试。 The 'ChannelFactory' way has many advantages then the auto-generating way: you can keep the comments of your SCi, and no need to update reference after SCI changes. 与自动生成方式相比,“ ChannelFactory”方式具有许多优点:您可以保留SCi的注释,而在SCI更改后无需更新引用。

In production, you may need to do some Singleton chache for performance, and separate SCI for Service implementation, so you can reference your SCI both in client and Service implementation. 在生产中,您可能需要做一些Singleton Chache来提高性能,并单独使用SCI来实现Service,因此您可以在客户端和Service实现中都引用SCI。

You have mentioned 'async', I think this may be a Binding or Behavior configuration issuse. 您已经提到“异步”,我认为这可能是“绑定”或“行为”配置问题。

private ChannelFactory CreateFactoryInstance<T>(string endpointConfigurationName, string endpointAddress)
{
    ChannelFactory factory = null;
    factory = new ChannelFactory<T>(endpointConfigurationName, new EndpointAddress(endpointAddress));
    factory.Open();
    return factory;
}

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

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