Gewusst wie: Hosten eines WCF-Diensts in einer verwalteten App

Wenn ein Dienst in einer verwalteten Anwendung gehostet werden soll, betten Sie den Code für den Dienst in den verwalteten Anwendungscode ein, definieren Sie entweder imperativ im Code, deklarativ über die Konfiguration oder mithilfe der Standardendpunkte einen Endpunkt für den Dienst, und erstellen Sie dann eine Instanz von ServiceHost.

Rufen Sie die Open-Methode der ServiceHost-Instanz auf, um den Empfang von Nachrichten zu starten. Damit wird ein Listener für den Dienst erstellt und geöffnet Diese Art des Hostings wird häufig auch als "Selbsthosting" bezeichnet, weil die verwaltete Anwendung selbst die für das Hosting erforderlichen Vorgänge ausführt. Um den Dienst zu schließen, rufen Sie die CommunicationObject.Close-Methode der ServiceHost-Instanz auf.

Ein Dienst kann auch in einem verwalteten Windows-Dienst in Internetinformationsdienste (IIS) oder in Windows Process Activation Service (WAS) gehostet werden. Weitere Informationen zu Hostingoptionen für einen Dienst finden Sie unter Hostingdienste.

Dienste in einer verwalteten Anwendung zu hosten ist die flexibelste Option, da sie für die Bereitstellung die geringsten Anforderungen an die Infrastruktur stellt. Weitere Informationen zum Hosten von Diensten in verwalteten Anwendungen finden Sie unter Hosten in einer verwalteten Anwendung.

Im folgenden Verfahren wird das Implementieren eines selbst gehosteten Diensts in einer Konsolenanwendung veranschaulicht.

Erstellen eines selbstgehosteten Diensts

  1. Erstellen einer neuen Konsolenanwendung:

    1. Öffnen Sie Visual Studio, und wählen Sie im Menü Datei die Option Neu>Projekt aus.

    2. Wählen Sie in der Liste Installierte Vorlagen die Option Visual C# oder Visual Basic und anschließend Windows Desktop aus.

    3. Wählen Sie die Vorlage Konsolen-App aus. Geben Sie SelfHost in das Feld Name ein, und wählen Sie dann OK aus.

  2. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf SelfHost, und wählen Sie Verweis hinzufügen aus. Wählen Sie auf der Registerkarte .NET die Option System.ServiceModel und dann OK aus.

    Tipp

    Wenn das Fenster Projektmappen-Explorer nicht angezeigt wird, wählen Sie im Menü Ansicht die Option Projektmappen-Explorer aus.

  3. Doppelklicken Sie im Fenster von Projektmappen-Explorer auf die Datei Program.cs oder Module1.vb, um sie ggf. im Codefenster zu öffnen. Fügen Sie am Anfang der Datei die folgenden Anweisungen ein:

    using System.ServiceModel;
    using System.ServiceModel.Description;
    
    Imports System.ServiceModel
    Imports System.ServiceModel.Description
    
  4. Definieren und implementieren Sie einen Dienstvertrag. In diesem Beispiel wird ein HelloWorldService-Element definiert, das auf Grundlage der Eingabe in den Dienst eine Nachricht zurückgibt.

    [ServiceContract]
    public interface IHelloWorldService
    {
        [OperationContract]
        string SayHello(string name);
    }
    
    public class HelloWorldService : IHelloWorldService
    {
        public string SayHello(string name)
        {
            return string.Format("Hello, {0}", name);
        }
    }
    
    <ServiceContract()>
    Public Interface IHelloWorldService
        <OperationContract()>
        Function SayHello(ByVal name As String) As String
    End Interface
    
    Public Class HelloWorldService
        Implements IHelloWorldService
    
        Public Function SayHello(ByVal name As String) As String Implements IHelloWorldService.SayHello
            Return String.Format("Hello, {0}", name)
        End Function
    End Class
    

    Hinweis

    Weitere Informationen zum Definieren und Implementieren einer Dienstschnittstelle finden Sie unter Vorgehensweise: Definieren eines Dienstvertrags und Vorgehensweise: Implementieren eines Dienstvertrags.

  5. Erstellen Sie am Beginn der Main-Methode eine Instanz der Uri-Klasse mit der Basisadresse des Diensts.

    Uri baseAddress = new Uri("http://localhost:8080/hello");
    
    Dim baseAddress As Uri = New Uri("http://localhost:8080/hello")
    
  6. Erstellen Sie eine Instanz der ServiceHost-Klasse, wobei Sie ein Type-Objekt, das den Diensttyp darstellt, und den URI (Uniform Resource Identifier) der Basisadresse ServiceHost(Type, Uri[]) übergeben. Aktivieren Sie die Veröffentlichung von Metadaten, und rufen Sie die Open-Methode für das ServiceHost-Objekt auf, um den Dienst zu initialisieren und auf den Empfang von Nachrichten vorzubereiten.

    // Create the ServiceHost.
    using (ServiceHost host = new ServiceHost(typeof(HelloWorldService), baseAddress))
    {
        // Enable metadata publishing.
        ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
        smb.HttpGetEnabled = true;
        smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
        host.Description.Behaviors.Add(smb);
    
        // Open the ServiceHost to start listening for messages. Since
        // no endpoints are explicitly configured, the runtime will create
        // one endpoint per base address for each service contract implemented
        // by the service.
        host.Open();
    
        Console.WriteLine("The service is ready at {0}", baseAddress);
        Console.WriteLine("Press <Enter> to stop the service.");
        Console.ReadLine();
    
        // Close the ServiceHost.
        host.Close();
    }
    
    ' Create the ServiceHost.
    Using host As New ServiceHost(GetType(HelloWorldService), baseAddress)
    
        ' Enable metadata publishing.
        Dim smb As New ServiceMetadataBehavior()
        smb.HttpGetEnabled = True
        smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
        host.Description.Behaviors.Add(smb)
    
        ' Open the ServiceHost to start listening for messages. Since
        ' no endpoints are explicitly configured, the runtime will create
        ' one endpoint per base address for each service contract implemented
        ' by the service.
        host.Open()
    
        Console.WriteLine("The service is ready at {0}", baseAddress)
        Console.WriteLine("Press <Enter> to stop the service.")
        Console.ReadLine()
    
        ' Close the ServiceHost.
        host.Close()
    
    End Using
    

    Hinweis

    In diesem Beispiel werden Standardendpunkte verwendet. Für diesen Dienst ist keine Konfigurationsdatei erforderlich. Wenn keine Endpunkte konfiguriert sind, wird von der Laufzeit ein Standardendpunkt für alle Basisadressen in jedem Dienstvertrag hinzugefügt, der vom Dienst implementiert wird. Weitere Informationen zu Standardendpunkten finden Sie unter Vereinfachte Konfiguration und Vereinfachte Konfiguration für WCF-Dienste.

  7. Drücken Sie STRG+UMSCHALT+B, um die Projektmappe zu erstellen.

Testen des Diensts

  1. Drücken Sie STRG+F5, um den Dienst auszuführen.

  2. Öffnen Sie den WCF-Testclient.

    Tipp

    Öffnen Sie zum Öffnen des WCF-Testclients die Entwicklereingabeaufforderung für Visual Studio, und führen Sie WcfTestClient.exe aus.

  3. Wählen Sie im Menü Datei den Befehl Dienst hinzufügen aus.

  4. Geben Sie im Adressfeld http://localhost:8080/hello ein, und klicken Sie auf OK.

    Tipp

    Stellen Sie sicher, dass der Dienst ausgeführt wird, oder ein Fehler tritt bei diesem Schritt auf. Haben Sie die Basisadresse im Code geändert, verwenden Sie in diesem Schritt die geänderte Basisadresse.

  5. Doppelklicken Sie im Knoten Meine Dienstprojekte auf SayHello. Geben Sie in der Liste Anforderung in der Spalte Wert Ihren Namen ein, und klicken Sie auf Aufrufen.

    In der Liste Antwort wird nun eine Antwortnachricht angezeigt.

Beispiel

Im folgenden Beispiel wird ein ServiceHost-Objekt als Host für einen Dienst des Typs HelloWorldService erstellt, und dann wird die Open-Methode der ServiceHost-Instanz aufgerufen. Im Code wird eine Basisadresse bereitgestellt, die Metadatenveröffentlichung ist aktiviert, und Standardendpunkte werden verwendet.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace SelfHost
{
    [ServiceContract]
    public interface IHelloWorldService
    {
        [OperationContract]
        string SayHello(string name);
    }

    public class HelloWorldService : IHelloWorldService
    {
        public string SayHello(string name)
        {
            return string.Format("Hello, {0}", name);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Uri baseAddress = new Uri("http://localhost:8080/hello");

            // Create the ServiceHost.
            using (ServiceHost host = new ServiceHost(typeof(HelloWorldService), baseAddress))
            {
                // Enable metadata publishing.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                host.Description.Behaviors.Add(smb);

                // Open the ServiceHost to start listening for messages. Since
                // no endpoints are explicitly configured, the runtime will create
                // one endpoint per base address for each service contract implemented
                // by the service.
                host.Open();

                Console.WriteLine("The service is ready at {0}", baseAddress);
                Console.WriteLine("Press <Enter> to stop the service.");
                Console.ReadLine();

                // Close the ServiceHost.
                host.Close();
            }
        }
    }
}
Imports System.ServiceModel
Imports System.ServiceModel.Description

Module Module1

    <ServiceContract()>
    Public Interface IHelloWorldService
        <OperationContract()>
        Function SayHello(ByVal name As String) As String
    End Interface

    Public Class HelloWorldService
        Implements IHelloWorldService

        Public Function SayHello(ByVal name As String) As String Implements IHelloWorldService.SayHello
            Return String.Format("Hello, {0}", name)
        End Function
    End Class

    Sub Main()
        Dim baseAddress As Uri = New Uri("http://localhost:8080/hello")

        ' Create the ServiceHost.
        Using host As New ServiceHost(GetType(HelloWorldService), baseAddress)

            ' Enable metadata publishing.
            Dim smb As New ServiceMetadataBehavior()
            smb.HttpGetEnabled = True
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
            host.Description.Behaviors.Add(smb)

            ' Open the ServiceHost to start listening for messages. Since
            ' no endpoints are explicitly configured, the runtime will create
            ' one endpoint per base address for each service contract implemented
            ' by the service.
            host.Open()

            Console.WriteLine("The service is ready at {0}", baseAddress)
            Console.WriteLine("Press <Enter> to stop the service.")
            Console.ReadLine()

            ' Close the ServiceHost.
            host.Close()

        End Using

    End Sub

End Module

Siehe auch