How to: Host a WCF service in a managed app

To host a service inside a managed application, embed the code for the service inside the managed application code, define an endpoint for the service either imperatively in code, declaratively through configuration, or using default endpoints, and then create an instance of ServiceHost.

To start receiving messages, call Open on ServiceHost. This creates and opens the listener for the service. Hosting a service in this way is often referred to as "self-hosting" because the managed application is doing the hosting work itself. To close the service, call CommunicationObject.Close on ServiceHost.

A service can also be hosted in a managed Windows service, in Internet Information Services (IIS), or in Windows Process Activation Service (WAS). For more information about hosting options for a service, see Hosting Services.

Hosting a service in a managed application is the most flexible option because it requires the least infrastructure to deploy. For more information about hosting services in managed applications, see Hosting in a Managed Application.

The following procedure demonstrates how to implement a self-hosted service in a console application.

Create a self-hosted service

  1. Create a new console application:

    1. Open Visual Studio and select New > Project from the File menu.

    2. In the Installed Templates list, select Visual C# or Visual Basic, and then select Windows Desktop.

    3. Select the Console App template. Type SelfHost in the Name box and then choose OK.

  2. Right-click SelfHost in Solution Explorer and select Add Reference. Select System.ServiceModel from the .NET tab and then choose OK.

    Tip

    If the Solution Explorer window is not visible, select Solution Explorer from the View menu.

  3. Double-click Program.cs or Module1.vb in Solution Explorer to open it in the code window, if it's not already open. Add the following statements at the top of the file:

    using System.ServiceModel;
    using System.ServiceModel.Description;
    
    Imports System.ServiceModel
    Imports System.ServiceModel.Description
    
  4. Define and implement a service contract. This example defines a HelloWorldService that returns a message based on the input to the service.

    [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
    

    Note

    For more information about how to define and implement a service interface, see How to: Define a Service Contract and How to: Implement a Service Contract.

  5. At the top of the Main method, create an instance of the Uri class with the base address for the service.

    Uri baseAddress = new Uri("http://localhost:8080/hello");
    
    Dim baseAddress As Uri = New Uri("http://localhost:8080/hello")
    
  6. Create an instance of the ServiceHost class, passing a Type that represents the service type and the base address Uniform Resource Identifier (URI) to the ServiceHost(Type, Uri[]). Enable metadata publishing, and then call the Open method on the ServiceHost to initialize the service and prepare it to receive messages.

    // 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
    

    Note

    This example uses default endpoints, and no configuration file is required for this service. If no endpoints are configured, then the runtime creates one endpoint for each base address for each service contract implemented by the service. For more information about default endpoints, see Simplified Configuration and Simplified Configuration for WCF Services.

  7. Press Ctrl+Shift+B to build the solution.

Test the service

  1. Press Ctrl+F5 to run the service.

  2. Open WCF Test Client.

    Tip

    To open WCF Test Client, open Developer Command Prompt for Visual Studio and execute WcfTestClient.exe.

  3. Select Add Service from the File menu.

  4. Type http://localhost:8080/hello into the address box and click OK.

    Tip

    Make sure the service is running or else this step fails. If you have changed the base address in the code, then use the modified base address in this step.

  5. Double-click SayHello under the My Service Projects node. Type your name into the Value column in the Request list, and click Invoke.

    A reply message appears in the Response list.

Example

The following example creates a ServiceHost object to host a service of type HelloWorldService, and then calls the Open method on ServiceHost. A base address is provided in code, metadata publishing is enabled, and default endpoints are used.

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

See also