How to: Host a WCF Service in a Managed Application

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 or declaratively through configuration, 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 System.ServiceModel.Channels.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 Windows Communication Foundation 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. For the working example on which this procedure is based, see the Self Host Sample.

To create a self-hosted service

  1. Define a service endpoint for the service through configuration.

  2. Create an interface for the service. See How to: Define a Windows Communication Foundation Service Contract.

  3. Implement the interface to create the service type. See How to: Implement a Windows Communication Foundation Service Contract. In the following example, the implementation is called MathService.

  4. Create a method to start the service. In this example, the Main method is used.

    ' Host the service within this EXE console application.
    Public Shared Sub Main()
        ' Create a ServiceHost for the CalculatorService type and use the base address from config.
        Using svcHost As New ServiceHost(GetType(CalculatorService))
            Try
                ' Open the ServiceHost to start listening for messages.
                svcHost.Open()
    
                ' The service can now be accessed.
                Console.WriteLine("The service is ready.")
                Console.WriteLine("Press <ENTER> to terminate service.")
                Console.WriteLine()
                Console.ReadLine()
    
                'Close the ServiceHost.
                svcHost.Close()
    
            Catch timeout As TimeoutException
                Console.WriteLine(timeout.Message)
                Console.ReadLine()
            Catch commException As CommunicationException
                Console.WriteLine(commException.Message)
                Console.ReadLine()
            End Try
        End Using
    
    End Sub
    
    // Host the service within this EXE console application.
    public static void Main()
    {
      using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
      {
        try
        {
          // Open the ServiceHost to start listening for messages.
          serviceHost.Open();
    
            // The service can now be accessed.
          Console.WriteLine("The service is ready.");
          Console.WriteLine("Press <ENTER> to terminate service.");
          Console.ReadLine();
    
          // Close the ServiceHost.
          serviceHost.Close();
        }
        catch (TimeoutException timeProblem)
        {
          Console.WriteLine(timeProblem.Message);
          Console.ReadLine();
        }
        catch (CommunicationException commProblem)
        {
          Console.WriteLine(commProblem.Message);
          Console.ReadLine();
        }
      }
    }
    
  5. Create an instance of the Uri class with the base address for the service. This example uses the static AppSettings property of the ConfigurationManager class to select a base address. Be sure to add a reference to the System.Configuration.dll to your project. The base address can then be set in the configuration file for the host application under the <appSettings> element.

  6. In the application's configuration file, add an <appSettings> element. Then use the <add> element with an appropriate key attribute. In this case, the key value matches the parameter that is passed to the AppSettings property in the previous step.

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

    ' Create a ServiceHost for the CalculatorService type and use the base address from config.
    Using svcHost As New ServiceHost(GetType(CalculatorService))
        Try
            ' Open the ServiceHost to start listening for messages.
            svcHost.Open()
    
            ' The service can now be accessed.
            Console.WriteLine("The service is ready.")
            Console.WriteLine("Press <ENTER> to terminate service.")
            Console.WriteLine()
            Console.ReadLine()
    
            'Close the ServiceHost.
            svcHost.Close()
    
        Catch timeout As TimeoutException
            Console.WriteLine(timeout.Message)
            Console.ReadLine()
        Catch commException As CommunicationException
            Console.WriteLine(commException.Message)
            Console.ReadLine()
        End Try
    End Using
    
      // Create a ServiceHost for the CalculatorService type and use
      // the base address from config.
      ServiceHost hostDefault = new
       ServiceHost(typeof(CalculatorService));
    
      TimeSpan closeTimeout = hostDefault.CloseTimeout;
    
      TimeSpan openTimeout = hostDefault.OpenTimeout;
    
    
      ServiceAuthorizationBehavior authorization =
          hostDefault.Authorization;
    
      ServiceCredentials credentials =
                      hostDefault.Credentials;
    
      ServiceDescription description =
              hostDefault.Description;
    
    
      int manualFlowControlLimit =
              hostDefault.ManualFlowControlLimit;
    
    
      NetTcpBinding portsharingBinding = new NetTcpBinding();
      hostDefault.AddServiceEndpoint(
    typeof(CalculatorService),
    portsharingBinding,
    "net.tcp://localhost/MyService");
    
    
      int newLimit = hostDefault.IncrementManualFlowControlLimit(100);
    
      using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
      {
          try
          {
              // Open the ServiceHost to start listening for messages.
              serviceHost.Open();
              // The service can now be accessed.
              Console.WriteLine("The service is ready.");
              Console.WriteLine("Press <ENTER> to terminate service.");
              Console.ReadLine();
    
              // Close the ServiceHost.
              serviceHost.Close();
          }
          catch (TimeoutException timeProblem)
          {
              Console.WriteLine(timeProblem.Message);
              Console.ReadLine();
          }
          catch (CommunicationException commProblem)
          {
              Console.WriteLine(commProblem.Message);
              Console.ReadLine();
          }
      }
    
  8. Call the Open method on the ServiceHost object.

To create an endpoint in configuration

  1. Add a configuration file to the same directory as the service assembly. For more information about configuration, see Configuring Bindings for Windows Communication Foundation Services.

Example

The following example creates a ServiceHost object to host a service of type CalculatorService, and then calls the Open method on ServiceHost. A base address is provided in code, while the relative path is provided in configuration.

Public Shared Sub Main()

    ' Create a proxy with the given client endpoint configuration.
    Dim wcfClient As New CalculatorClient()

    Try
        ' Call the Add service operation.
        Dim value1 As Double = 100D
        Dim value2 As Double = 15.99D
        Dim result As Double = wcfClient.Add(value1, value2)
        Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result)

        ' Call the Subtract service operation.
        value1 = 145D
        value2 = 76.54D
        result = wcfClient.Subtract(value1, value2)
        Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result)

        ' Call the Multiply service operation.
        value1 = 9D
        value2 = 81.25D
        result = wcfClient.Multiply(value1, value2)
        Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result)

        ' Call the Divide service operation.
        value1 = 22D
        value2 = 7D
        result = wcfClient.Divide(value1, value2)
        Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result)
        wcfClient.Close()

    Catch timeout As TimeoutException
        Console.WriteLine(timeout.Message)
        wcfClient.Abort()
    Catch commException As CommunicationException
        Console.WriteLine(commException.Message)
        wcfClient.Abort()
    End Try
    Console.WriteLine()
    Console.WriteLine("Press <ENTER> to terminate client.")
    Console.ReadLine()
End Sub
using System;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples
{
    // The service contract is defined in code generated from the service by the svcutil tool.

    // Client implementation code.
    class Client
    {
        static void Main()
        {
            // Create a WCF client object.
            CalculatorClient wcfClient = new CalculatorClient();
            try
            {
              // Call the Add service operation.
              double value1 = 100.00D;
              double value2 = 15.99D;
              double result = wcfClient.Add(value1, value2);
              Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

              // Call the Subtract service operation.
              value1 = 145.00D;
              value2 = 76.54D;
              result = wcfClient.Subtract(value1, value2);
              Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

              // Call the Multiply service operation.
              value1 = 9.00D;
              value2 = 81.25D;
              result = wcfClient.Multiply(value1, value2);
              Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

              // Call the Divide service operation.
              value1 = 22.00D;
              value2 = 7.00D;
              result = wcfClient.Divide(value1, value2);
              Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

              // Closing the client gracefully closes the connection and cleans up resources.
              wcfClient.Close();
            }
            catch (TimeoutException timeout)
            {
              Console.WriteLine(timeout.Message);
              Console.ReadLine();
              wcfClient.Abort();
            }
            catch (CommunicationException commProblem)
            {
              Console.WriteLine(commProblem.Message);
              Console.ReadLine();
              wcfClient.Abort();
            } 
          
          Console.WriteLine();
          Console.WriteLine("Press <ENTER> to terminate client.");
          Console.ReadLine();
        }
    }
}

To create a client for the service using the ServiceMetadata Utility Tool (svcutil.exe), the binding for the endpoint must use the HTTP protocol. For more information about bindings, see Using Bindings to Configure Services and Clients and System-Provided Bindings. For the complete sample on which this topic is based, see Self-Host sample.

See Also

Tasks

How to: Host a WCF Service in IIS
How to: Define a Windows Communication Foundation Service Contract
How to: Implement a Windows Communication Foundation Service Contract

Reference

Uri
AppSettings
ConfigurationManager

Concepts

Hosting Windows Communication Foundation Services
Using Bindings to Configure Services and Clients
System-Provided Bindings

Other Resources

Self Host
Service Metadata Utility Tool (svcutil.exe)


© 2007 Microsoft Corporation. All rights reserved.
Last Published: 2010-03-21