【问题标题】:Generate client for only one of the Service Contract interfaces available on a WCF service仅为 WCF 服务上可用的服务合同接口之一生成客户端
【发布时间】:2011-12-13 23:29:11
【问题描述】:

我目前正在重构一个大型 WCF 服务,该服务由多个不同客户端应用程序使用的一个服务合同接口(以下简称“SCI”)组成。我已经拆分了 SCI,因此对于每种类型的客户端应用程序,都有一个特定于其所需操作的 SCI。 SCI 的一些共享部分在基础 SCI 中定义,客户端应用程序特定的 SCI 继承该基础 SCI。

有一个服务类可以实现所有客户端特定的 SCI。共享基础 SCI 存在菱形接口继承情况这一事实有时意味着同一操作可通过多个 SCI 获得。自动生成客户端时(尤其是使用异步客户端方法),生成的代码有很多丑陋的<generated-type>1,2,3 等...

为了避免这种情况,我想为每个客户端应用程序添加一个服务引用,该服务引用只为与该特定应用程序相关的 SCI 生成一个客户端。这应该不会导致由于相同的功能出现在不同的 SCI 上而出现的问题。

这可能吗?

在这种情况下实现模块化和代码重用的任何其他技巧也将不胜感激。

【问题讨论】:

    标签: c# .net wcf service-reference servicecontract


    【解决方案1】:

    您要做的是创建一个服务合同接口(您可以手动执行此操作,将其从原始服务实现中提取或自动生成然后将其复制出来)。

    然后,不要使用服务引用,而是使用通道工厂绑定到您的服务(如下所示)。这是一种更好的引用 WCF 服务的方式。

    您需要以下 refs 来执行此操作:

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

    然后你可以使用以下内容:

         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();
    

    【讨论】:

    • 所以这意味着要使用服务的通道来实现客户端?是否可以通过自动生成的异步操作获取自动生成的客户端类型?
    • 是的,您可以通过使用 ASYNC 版本装饰 WCF 服务来做到这一点,请参阅这篇文章:msdn.microsoft.com/en-us/library/bb885132.aspx IE: [OperationContract(AsyncPattern = true)] IAsyncResult BeginDivide(double n1, double n2, AsyncCallback 回调, 对象状态);双 EndDivide(IAsyncResult ar);给出一个异步方法
    • 我了解了如何手动使操作异步,但是当代码生成器可以为您执行此操作时,为数十个操作执行此操作似乎很难看。我仍然想知道如何获取特定服务合同的代码生成。
    【解决方案2】:

    卢克的建议值得一试。 'ChannelFactory' 方式比自动生成方式有很多优点:可以保留 SCi 的 cmets,而且 SCI 更改后无需更新引用。

    在生产中,您可能需要对性能进行一些 Singleton chache,并为 Service 实现单独的 SCI,以便您可以在客户端和 Service 实现中引用您的 SCI。

    您提到了“异步”,我认为这可能是绑定或行为配置问题。

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

    【讨论】:

    • 我想我明天回去工作时试试渠道工厂方法,因为你们俩都推荐它。
    猜你喜欢
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    相关资源
    最近更新 更多