WCF :: ServiceHost& AddServiceEndpoint:Arguments类型是否被反转?

时间:2009-06-01 04:33:56

标签: .net wcf servicehost

虽然我正在努力学习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

连接以获取Dog或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应该是接受界面的人吗?

顺便说一句,我并不是迂腐......我只是老老实实地想要了解,因为我确信我在这里错过了一些东西。

3 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:2)

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

记住,你不认识我,我不认识你。我们交换消息,而不是对象。我不想要你的猫狗。除非我们事先达成协议,否则我不知道如何处理你给我的猫或狗。你告诉我我能做什么,然后你就可以用方法来做。以下是关于内部数据与外部数据的good article

答案 2 :(得分:1)

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

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

例如,您可能拥有一个服务,该服务通过MSMQ公开单向合同,并通过HTTP公开双向合同。或者它可能在一个URL上公开JSON合同而在另一个URL上公开XML。