WCF :: ServiceHost & AddServiceEndpoint: são argumentos tipos revertida?
-
06-09-2019 - |
Pergunta
Enquanto eu estou tentando aprender WCF, e parece bastante simples e direta, eu vim através de uma situação estranha ... pelo menos parece estranho para mim.
Por que é que o ctor ServiceHost leva uma classe concreta, eo AddServiceEndpoint leva a interface, e não vice-versa? Parece que o último é mais lógico do ponto de vista OOP.
Considere o seguinte:
[ServiceContract]
interface IVocalAnimal
{
[OperationContract]
string MakeSound();
}
...
public class Dog : IVocalAnimal
{
public string MakeSound()
{
return("Woof!");
}
}
...
public class Cat : IVocalAnimal
{
public string MakeSound()
{
return("Meeooow!");
}
}
Então, agora nós wanto criar um serviço "AnimalSound" que você pode conectar para obter o som de um cão ou um gato via / AnimalSoundService / Cão ou / 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");
...
Mas o código acima não irá compilar como por algum motivo (s) eu não entendo muito bem, o ctor ServiceHost quer a classe concreta (por isso ou cão ou gato) eo EndPoint quer o Interface.
Então, qual é a razão, é não vice-versa como parece-me mais natural que o desfecho mais fina granularidade suporta uma implementação específica (assim você pode atingir implementações específicas do contrato por endereço de endpoint), enquanto o ServiceHost mais geral deve ser o único a aceitar a interface?
Btw, eu não estou sendo pedantic..I apenas estou honestamente tentando entender como eu tenho certeza que sou eu que perdi alguma coisa aqui.
Solução
Quando você cria o ServiceHost, você está criando o serviço real, por isso deve ser concreto.
Os seus endpoints, por outro lado, são o que seus clientes ver. Você não necessariamente quer que seus clientes para saber sua implementação - eles devem apenas obter a definição de interface
.O endpoind suporta uma implementação específica, como você diz: qualquer um que você usa quando você criar o ServiceHost. O objetivo da endpoints, não é fornecer várias implementações, mas para fornecer vários protocolos / ligações para aceder a uma única implementação.
Se você quiser serviços do cão e gato distintas, eu acredito que você vai precisar de duas ServiceHosts, cada um com um endpoint NetNamedPipeBinding.
Outras dicas
Eu vejo o que você está pensando. Do ponto de vista OOP faz sentido, mas isso não é uma perspectiva de serviço. Um serviço é um grupo de operações. Aquele grupo de operações é definido em um contrato. Você pode usar classes para modelar os contratos de serviços, mas a maioria das interfaces de uso, porque as interfaces são um modelo mais direto. MSDN tem um discussão muito boa desses conceitos.
Lembre-se, você não me conhece e eu não te conheço. Nós trocar mensagens, e não objetos. Eu não quero que os cães e gatos de você. Eu não saberia o que fazer com um gato ou um cão que você me deu a menos que tenhamos um acordo prévio. Você me diz que eu posso fazer e eu chamar métodos em que você faça isso. Aqui está um bom artigo em dados no interior versus os dados do lado de fora .
Eu tenho que discordar um pouco com as outras respostas. Enquanto eles são tecnicamente correto de certa forma, sinto-me a razão mais importante para que isso seja do jeito que está tem pouco a ver com escondendo a implementação ou usando classes vs interfaces para definir contratos de serviços.
É muito mais óbvia porque é do jeito que é, se você levar em conta o fato de que uma única implementação do serviço pode expor vários pontos de extremidade. Cada poder endpoint, ou talvez não, expor um contrato diferente, e cada um pode ser exposto em um diferente de ligação, por tudo o que sabe.
Por exemplo, você pode ter um serviço que expõe um contrato de um caminho MSMQ e um contrato de duas vias através de HTTP. Ou talvez ele expõe um contrato JSON em um URL e um um XML em outra.