代码之家  ›  专栏  ›  技术社区  ›  Turing Complete

WCF服务继承

  •  4
  • Turing Complete  · 技术社区  · 15 年前

    我有一个非常复杂的服务主机,它由多个双工服务组成。它们提供了一些共同的功能(连接、断开连接、保持连接等),但除此之外,它们每个都提供了非常具体的功能。

    我的所有服务都继承自一个公共基类(抽象)。

    因此,我还负责客户端应用程序的一部分,我希望在基类中处理连接、断开、保持活动的ping和重新连接(等等)的行政官僚处理,这样我就可以遵守dry原则,并强制其他开发人员不执行自己的连接处理。

    有没有办法让wcf公开服务基类,这样我就可以为在客户机应用程序中浪费时间而创建一个公共包装类?

    我真的不想看到未来客户端组件的每个开发人员都创建自己的包装器?

    如果你允许咆哮:

    为什么,为什么,为什么微软如此完全无视清洁代码开发的最佳实践和基本原则?这和这个inotifypropertieschanged一样,它强制一个人编写大量不必要的、重复的代码,而不是提供一个简单的属性来通知属性…

    1 回复  |  直到 15 年前
        1
  •  4
  •   Richard Beier    15 年前

    我不知道如何让多个WCF代理从公共基类继承。您可以手动编辑添加服务引用时生成的代码,但这不利于维护性。

    但是,如果在客户机和服务器之间共享契约程序集,则可以让多个代理使用相同的基本接口。然后,您可以编写一个客户端助手类(可能使用扩展方法)来在基本接口上执行公共操作。您也可以将助手类放在共享程序集中,并从多个客户端重用它。

    不过,我还没有使用双面装订,所以我不确定这是否会带来并发症。

    例如,假设您有两个服务计算器和echo,并且每个都需要实现一个keepalive方法。您可以定义三个服务契约接口:

    [ServiceContract]
    public interface IStatefulService
    { 
        [OperationContract]
        void KeepAlive(int sessionID);
    }
    
    [ServiceContract]
    public interface ICalculator : IStatefulService
    {
        [OperationContract]
        int Add(int a, int b);
    }
    
    [ServiceContract]
    public interface IEcho : IStatefulService
    {
        [OperationContract]
        string Echo(string message);
    }
    

    您可以将服务契约接口放在客户机和服务器共享的公共类库中。

    在服务器上,您将拥有ServiceBase类,它将实现IStatefulService并包含Keepalive处理代码。您将拥有一个从ServiceBase派生并实现iCalculator的具体CalculatorService;以及一个从ServiceBase派生并实现iecho的具体EchoService。

    在客户机上,您需要两个代理,每个服务一个。理论上,您可以使用“添加服务引用”生成代理,使用“从引用的程序集重用类型”复选框-但我遇到了这个问题。相反,您可以直接使用ChannelFactory,如下所示:

    var echoer = (new ChannelFactory<IEcho>("")).CreateChannel();
    Console.WriteLine(echoer.Echo("hello"));
    
    var calculator = (new ChannelFactory<ICalculator>("")).CreateChannel();
    Console.WriteLine(calculator.Add(2, 3));
    

    (在生产代码中,您希望重用通道工厂,而不是像这样即时创建它们。您将处理这些代理,并且会有错误处理…)

    您还需要在客户机配置文件中设置端点。

    一旦两个代理共享一个基本接口,就可以编写一个实用程序类来帮助您使用该接口。