2009-06-01 10 views
1

Während ich versuche, WCF zu lernen, und es scheint geradlinig genug, kam ich durch eine seltsame Situation ... zumindest scheint es mir seltsam.WCF :: ServiceHost & AddServiceEndpoint: Sind die Argumenttypen umgekehrt?

Warum nimmt der ServiceHost ctor eine konkrete Klasse und der AddServiceEndpoint die Schnittstelle und nicht umgekehrt? es scheint, dass letzteres vom OOP-Standpunkt aus logischer ist.

Betrachten Sie das folgende:

[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, jetzt wir "AnimalSound" Service wanto erstellen, die Sie den Klang eines Hundes oder einer Katze über/AnimalSoundService/Hund oder/AnimalSoundService/Cat

erhalten verbinden kann
... 
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"); 
... 

Aber der obige Code wird nicht so aus irgendeinem Grund zusammenstellen (s) ich verstehe nicht ganz, will der Servicehost ctor die konkrete Klasse (also entweder Hund oder Katze) und die EndPoint will die Schnittstelle.

Aus diesem Grund ist es nicht umgekehrt, denn es scheint mir natürlicher zu sein, dass der feinere Granularitätsendpunkt eine spezifische Implementierung unterstützt (sodass Sie bestimmte Implementierungen des Vertrags pro Endpunktadresse treffen können), während der allgemeinere ServiceHost sollte derjenige sein, der die Schnittstelle akzeptiert?

Btw, ich bin nicht pedantisch..ich versuche nur ehrlich zu verstehen, da ich mir sicher bin, dass ich hier etwas verpasst habe.

Antwort

2

Wenn Sie den ServiceHost erstellen, erstellen Sie den eigentlichen Service, also muss er konkret sein.

Auf der anderen Seite sehen Ihre Kunden Ihre Endpunkte. Sie möchten nicht unbedingt, dass Ihre Kunden Ihre Implementierung kennen - sie sollten nur die Schnittstellendefinition erhalten.

Die endpoind DOES unterstützt eine spezifische Implementierung, wie Sie sagen: welche Sie beim Erstellen des ServiceHost verwenden. Der Zweck von Endpunkten besteht nicht darin, mehrere Implementierungen bereitzustellen, sondern mehrere Protokolle/Bindungen bereitzustellen, um auf eine einzelne Implementierung zuzugreifen.

Wenn Sie unterschiedliche Hunde- und Katzenservices wünschen, benötigen Sie zwei ServiceHosts mit jeweils einem NetNamedPipeBinding-Endpunkt.

+0

"Zweck von Endpunkten ist nicht die Bereitstellung mehrerer Implementierungen, sondern die Bereitstellung mehrerer Protokolle/Bindungen für den Zugriff auf eine einzige Implementierung" <--- OK, macht Sinn. Ich habe es rückwärts verstanden. Aber sagen Sie, dass meine ServiceHost-Basis ist "http: // localhost: 8000/AnimalSoundService/Service" und ich HTTP-Bindung verwenden, das bedeutet, dass ein anderer ServiceHost nicht in der Lage sein wird, den gleichen Port zu teilen, und Client muss eine Verbindung herstellen verschiedene Häfen? – Futurist

+0

Nach einem kleinen Experiment habe ich festgestellt, dass 2 serviceHost Instanzen den gleichen Port teilen können. Ich denke, um mein Beispiel zu verbessern, erstelle ich 2 serviceHost mit 2 verschiedenen Basisadressen: net.pipe: // localhost/AnimalSoundService/Dog und net.pipe: // localhost/AnimalSoundService/Cat ..Es macht jetzt mehr Sinn. Danke Jay. – Futurist

+0

Das Abhören für jeden Dienst an seinem eigenen Port ist eine Option. Ich habe eine Lösung, die diesen Ansatz verwendet - 3 Dienste, 3 Ports, aber nur beim Debuggen. Hosting in IIS, das ist natürlich kein Problem - jeder Dienst ist per URL adressierbar. Der Schlüssel zum Teilen Ihrer Dienste an einem einzigen Port ist Net.TCP Port Sharing, das speziell für WCF ist: http://msdn.microsoft.com/en-us/library/aa395195.aspx – Jay

2

Ich sehe, was Sie denken. Aus Sicht der OOP ist es sinnvoll, aber das ist keine Service-Perspektive. Ein Service ist eine Gruppe von Operationen. Diese Gruppe von Operationen ist in einem Vertrag definiert. Sie können Klassen verwenden, um Serviceverträge zu modellieren, aber die meisten verwenden Schnittstellen, weil Schnittstellen ein direkteres Modell sind. MSDN hat eine very good discussion dieser Konzepte.

Denken Sie daran, Sie kennen mich nicht und ich kenne Sie nicht. Wir tauschen Nachrichten aus, nicht Objekte. Ich will keine Katzen und Hunde von dir. Ich würde nicht wissen, was ich mit einer Katze oder einem Hund tun soll, die du mir gegeben hast, es sei denn, wir haben vorher eine Vereinbarung getroffen. Sie sagen mir, was ich tun kann, und ich rufe Methoden an, damit Sie es tun. Hier ist ein good article auf Daten auf der Innenseite im Vergleich zu Daten auf der Außenseite.

+0

Danke für die Links. Ich denke also, was Leute tun, ist entweder eine Mega-Concrete-Service-Klasse zu erstellen oder eine ServiceHost-Instanz pro konkreter Klasse zu erstellen. – Futurist

+0

Könnten Sie bitte http://stackoverflow.com/questions/9483286/understanding-data-outside-of-service-soa beantworten? – Lijo

1

Ich muss ein wenig mit den anderen Antworten widersprechen. Obwohl sie in gewisser Hinsicht technisch korrekt sind, habe ich den Eindruck, dass der wichtigste Grund dafür nicht darin besteht, die Implementierung zu verbergen oder Klassen oder Schnittstellen zu verwenden, um Serviceverträge zu definieren.

Es ist viel offensichtlicher, warum es so ist, wenn man berücksichtigt, dass eine einzelne Service-Implementierung mehrere Endpunkte aussetzen kann.Jeder Endpunkt kann einen anderen Vertrag enthalten oder auch nicht, und jeder kann auf einer anderen Bindung verfügbar gemacht werden, für alles, was Sie wissen.

Beispielsweise verfügen Sie möglicherweise über einen Dienst, der einen einseitigen Vertrag über MSMQ und einen bidirektionalen Vertrag über HTTP verfügbar macht. Oder vielleicht legt es einen JSON-Vertrag für eine URL und eine XML-Datei für eine andere offen.

+0

Ich vermute, was ich habe ein Problem mit ist, dass die Service-Implementierung eine riesige konkrete Klasse ist, und die Endpunkte sind die Vertragsschnittstelle ... – Futurist

Verwandte Themen