WCF::ServiceHost& AddServiceEndpoint:参数类型是否颠倒?
当我尝试学习 WCF 时,它看起来很简单,但我遇到了一个奇怪的情况......至少对我来说似乎很奇怪。
为什么 ServiceHost ctor 采用具体类,而 AddServiceEndpoint 采用 Interface,而不是相反? 从 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");
...
但由于某种原因,上述代码将无法编译( s)我不太明白,ServiceHost ctor 需要具体的类(因此 Dog 或 Cat),而 EndPoint 需要 Interface。
那么,反之亦然的原因是什么,因为在我看来,更精细的粒度端点支持特定的实现(因此您可以命中每个端点地址的合约的特定实现),而更通用的 ServiceHost 应该是更自然的接受接口?
顺便说一句,我并不是迂腐……我只是诚实地试图理解,因为我确信我在这里错过了一些东西。
While I am trying to learn WCF, and it seems straight-forward enough, I came through an odd situation...at least it seems odd to me.
Why is it that the ServiceHost ctor takes a concrete class, and the AddServiceEndpoint takes the Interface, and not vice versa? it seems the latter is more logical from an OOP standpoint.
Consider the following:
[ServiceContract]
interface IVocalAnimal
{
[OperationContract]
string MakeSound();
}
...
public class Dog : IVocalAnimal
{
public string MakeSound()
{
return("Woof!");
}
}
...
public class Cat : IVocalAnimal
{
public string MakeSound()
{
return("Meeooow!");
}
}
So now we wanto create an "AnimalSound" service that you can connect to get the sound of a Dog or a Cat via /AnimalSoundService/Dog or /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");
...
But the above code will not compile as for some reason(s) I don't quite understand, the ServiceHost ctor wants the concrete class (so either Dog or Cat) and the EndPoint wants the Interface.
So what is the reason it is not vice-versa as it seems to me more natural that the finer granularity endpoint supports a specific implementation (so you could hit specific implementations of the contract per endpoint address) while the more general ServiceHost should be the one to accept the interface?
Btw, I am not being pedantic..I am just honestly trying to understand as I am sure it is I that missed something here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您创建 ServiceHost 时,您正在创建实际的服务,因此它必须是具体的。
另一方面,您的端点是您的客户所看到的。 您不一定希望您的客户知道您的实现——他们应该只获取接口定义。
正如您所说,端点确实支持特定的实现:无论您在创建 ServiceHost 时使用哪个实现。 端点的目的不是提供多个实现,而是提供多个协议/绑定来访问单个实现。
如果您想要不同的 Dog 和 Cat 服务,我相信您将需要两个 ServiceHost,每个 ServiceHost 都有一个 NetNamedPipeBinding 端点。
When you create the ServiceHost, you are creating the actual service, so it must be concrete.
Your endpoints, on the other hand, are what your clients see. You don't necessarily want your clients to know your implementation -- they should just get the interface definition.
The endpoind DOES support a specific implementation, as you say: whichever one you use when you create the ServiceHost. The purpose of endpoints, is not to provide multiple implementations, but to provide multiple protocols/bindings to access a single implementation.
If you want distinct Dog and Cat services, I believe you'll need two ServiceHosts, each with one NetNamedPipeBinding endpoint.
我明白你在想什么。 从面向对象编程的角度来看这是有道理的,但这不是服务的角度。 服务是一组操作。 该组操作是在合同中定义的。 您可以使用类来建模服务契约,但大多数使用接口,因为接口是更直接的模型。 MSDN 对这些概念有非常好的讨论。
记住,你不认识我,我也不认识你。 我们交换消息,而不是对象。 我不要你的猫和狗。 除非我们事先同意,否则我不知道如何处理你送给我的猫或狗。 你告诉我我能做什么,然后我调用你的方法来做到这一点。 这是一篇关于内部数据与外部数据的好文章 。
I see what you thinking. From an OOP perspective it makes sense, but that's not a service perspective. A service is a group of operations. That group of operations is defined in a contract. You can use classes to model service contracts, but most use interfaces because interfaces are a more direct model. MSDN has a very good discussion of those concepts.
Remember, you don't know me and I don't know you. We exchange messages, not objects. I don't want cats and dogs from you. I would not know what to do with a cat or a dog you gave me unless we have prior agreement. You tell me what I can do and I call methods on you to do it. Here's a good article on data on the inside versus data on the outside.
我不得不有点不同意其他答案。 虽然它们在某种程度上在技术上是正确的,但我认为最重要的原因是它的方式与隐藏实现或使用类与接口来定义服务契约无关。
如果考虑到单个服务实现可以公开多个端点这一事实,那么为什么会是这样就更明显了。 据您所知,每个端点可能会也可能不会公开不同的合约,并且每个端点都可以在不同的绑定上公开。
例如,您可能有一项服务公开通过 MSMQ 的单向协定和通过 HTTP 的双向协定。 或者它可能在一个 URL 上公开 JSON 契约,在另一个 URL 上公开 XML 契约。
I have to disagree a bit with the other answers. While they are technically correct in a way, I feel the most important reason for this to be the way it is has little to do with hiding the implementation or using classes vs interfaces to define service contracts.
It's a lot more obvious why it is the way it is if you take into account the fact that a single service implementation can expose multiple endpoints. Each endpoint might, or might not, expose a different contract, and each one could be exposed on a different binding, for all you know.
For example, you might have a service that exposes a one-way contract over MSMQ and a two-way contract over HTTP. Or perhaps it exposes a JSON contract on one URL and an XML one on another.