【问题标题】:WCF:: ServiceHost & AddServiceEndpoint: Are Arguments types reversed?WCF:: ServiceHost & AddServiceEndpoint: 参数类型是否反转?
【发布时间】:2009-06-01 04:33:55
【问题描述】:

虽然我正在尝试学习 WCF,而且它看起来很简单,但我遇到了一个奇怪的情况……至少在我看来这很奇怪。

为什么 ServiceHost ctor 采用具体类,而 AddServiceEndpoint 采用接口,反之则不然?从 OOP 的角度来看,后者似乎更合乎逻辑。

考虑以下几点:

    [ServiceContract]
    interface IVocalAnimal
    {
        [OperationContract]
        string MakeSound();
    }
  ...      
  public class Dog : IVocalAnimal
  {
     public string MakeSound()
     {
        return("Woof!");
     }
  }
 ...
 public class Cat : IVocalAnimal
  {
     public string MakeSound()
     {
        return("Meeooow!");
     }
  }

所以现在我们想要创建一个“AnimalSound”服务,您可以通过 /AnimalSoundService/Dog 或 /AnimalSoundService/Cat 连接它以获取狗或猫的声音

...
Uri baseAddress = new Uri("net.pipe://localhost/AnimalSoundService");
ServiceHost serviceHost = new ServiceHost(typeof(IVocalAnimal), baseAddress);
serviceHost.AddServiceEndpoint(typeof(Dog), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "Dog");
serviceHost.AddServiceEndpoint(typeof(Cat), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "Cat");
...

但是上面的代码由于某些我不太明白的原因无法编译,ServiceHost ctor 想要具体的类(所以是 Dog 或 Cat),而 EndPoint 想要接口。

那么为什么不是反之亦然,因为在我看来,更细粒度的端点支持特定的实现更自然(因此您可以针对每个端点地址命中合同的特定实现),而更通用的 ServiceHost 应该是接受接口的那个吗?

顺便说一句,我不是迂腐。我只是诚实地试图理解,因为我确信是我在这里错过了一些东西。

【问题讨论】:

    标签: .net wcf servicehost


    【解决方案1】:

    当您创建 ServiceHost 时,您正在创建实际的服务,因此它必须是具体的。

    另一方面,您的端点就是您的客户所看到的。您不一定希望您的客户知道您的实现——他们应该只获得接口定义。

    正如您所说,端点确实支持特定的实现:无论您在创建 ServiceHost 时使用哪个。端点的目的不是提供多个实现,而是提供多个协议/绑定来访问单个实现。

    如果您想要不同的 Dog 和 Cat 服务,我相信您需要两个 ServiceHost,每个都有一个 NetNamedPipeBinding 端点。

    【讨论】:

    • “端点的目的,不是提供多个实现,而是提供多个协议/绑定来访问单个实现”localhost:8000/AnimalSoundService/Service”并且我使用 HTTP 绑定,这意味着另一个 ServiceHost 将无法共享同一个端口,并且客户端必须连接到不同的端口?
    • 经过一个小实验,我发现 2 个 serviceHost 实例可以共享同一个端口。所以我想为了让我的示例正常工作,你创建了 2 个具有 2 个不同基址的 serviceHost:net.pipe://localhost/AnimalSoundService/Dog 和 net.pipe://localhost/AnimalSoundService/Cat ..它现在更有意义了。谢谢杰。
    • 在自己的端口上监听每个服务是一种选择。我有一个使用这种方法的解决方案——3 个服务,3 个端口,但仅限于调试时。在 IIS 中托管,这显然不是问题——每个服务都可以通过 URL 寻址。在单个端口上共享服务的关键是 Net.TCP 端口共享,特别适用于 WCF:msdn.microsoft.com/en-us/library/aa395195.aspx
    【解决方案2】:

    我明白你在想什么。从 OOP 的角度来看,这是有道理的,但这不是服务的角度。服务是一组操作。该组操作在合同中定义。您可以使用类来为服务契约建模,但大多数使用接口,因为接口是一种更直接的模型。 MSDN 有一个very good discussion 这些概念。

    记住,你不认识我,我也不认识你。我们交换消息,而不是对象。我不想要你的猫和狗。除非我们事先达成协议,否则我不知道如何处理你给我的猫或狗。你告诉我我能做什么,我会调用你的方法来做到这一点。这是内部数据与外部数据的good article

    【讨论】:

    • 感谢您的链接。所以我猜人们所做的要么是创建一个大型具体服务类,要么为每个具体类创建一个 serviceHost 实例。
    【解决方案3】:

    我不得不对其他答案有点不同意。虽然它们在某种程度上在技术上是正确的,但我认为最重要的原因是它与隐藏实现或使用类与接口来定义服务契约无关。

    如果您考虑到单个服务实现可以公开多个端点这一事实,那么为什么会这样会更明显。如您所知,每个端点可能会或可能不会暴露不同的合约,并且每个端点都可能会暴露在不同的绑定上。

    例如,您可能有一项服务公开了一个通过 MSMQ 的单向契约和一个通过 HTTP 的双向契约。或者它可能在一个 URL 上公开 JSON 合约,在另一个 URL 上公开 XML。

    【讨论】:

    • 我想我遇到的问题是服务实现是一个巨大的具体类,端点是合同接口......
    猜你喜欢
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 2010-12-02
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    相关资源
    最近更新 更多