如何:在托管应用中托管 WCF 服务

若要在托管应用程序中承载某项服务,请在托管应用程序代码内嵌入该服务的代码,在代码中强制定义、通过配置以声明的方式定义或者使用默认终结点定义该服务的终结点,然后创建 ServiceHost 的实例。

若要开始接收消息,请调用 Open 上的 ServiceHost。 这样即可创建并打开服务的侦听器。 以这种方式承载服务的做法通常称为“自承载”,原因是托管的应用程序会自己处理承载工作。 若要关闭服务,请调用 CommunicationObject.Close 上的 ServiceHost

在托管的 Windows 服务中、在 Internet Information Services (IIS) 中或在 Windows 进程激活服务 (WAS) 中也可以承载服务。 有关服务的托管选项的详细信息,请参阅托管服务

在托管应用程序中承载服务是一个非常灵活的选项,因为采用此选项时,所需部署的基础结构最少。 有关在托管应用程序中托管服务的信息,请参阅托管应用程序中的托管

下面的过程演示如何在控制台应用程序中实现自承载的服务。

创建自承载服务

  1. 创建新的控制台应用程序:

    1. 打开 Visual Studio,然后从“文件”菜单中选择“新建”>“项目”。

    2. 在“已安装的模板”列表中,选择“Visual C#”或“Visual Basic”,然后选择“Windows Desktop”。

    3. 选择“控制台应用”模板。 在“名称”框中,键入 SelfHost,然后选择“确定”。

  2. 在“解决方案资源管理器”中右键单击“SelfHost”,然后选择“添加引用”。 从“.NET”选项卡中选择“System.ServiceModel”,然后单击“确定”。

    提示

    如果未显示“解决方案资源管理器”窗口,请从“视图”菜单中选择“解决方案资源管理器”。

  3. 如果文件还是没打开,请在“解决方案资源管理器”中双击“Program.cs”或“Module1.vb”,以在代码窗口中打开它。 将下面的语句添加到文件顶部:

    using System.ServiceModel;
    using System.ServiceModel.Description;
    
    Imports System.ServiceModel
    Imports System.ServiceModel.Description
    
  4. 定义和实现服务协定。 此示例定义了一个 HelloWorldService,它基于对服务的输入返回消息。

    [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
    

    注意

    若要详细了解如何定义和实现服务接口,请参阅 如何:定义服务协定如何:实现服务协定

  5. Main 方法的顶部,使用该服务的基址创建 Uri 类的实例。

    Uri baseAddress = new Uri("http://localhost:8080/hello");
    
    Dim baseAddress As Uri = New Uri("http://localhost:8080/hello")
    
  6. 创建 ServiceHost 类的实例,并将表示服务类型的 Type 和基址统一资源标识符 (URI) 传递到 ServiceHost(Type, Uri[])。 启用元数据发布,然后调用 Open 上的 ServiceHost 方法,以初始化服务并使其准备好接收消息。

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

    注意

    此示例使用默认终结点,且该服务不需要任何配置文件。 如果未配置任何终结点,则运行时会为该服务实现的每个服务协定的每个基地址创建一个终结点。 有关默认终结点的详细信息,请参阅简化配置WCF 服务的简化配置

  7. 按 CtrlShiftB 以生成解决方案。

测试服务

  1. 按 Ctrl+F5 运行服务。

  2. 打开“WCF 测试客户端”。

    提示

    若要打开“WCF 测试客户端”,请打开 Visual Studio 的开发人员命令提示,并执行“WcfTestClient.exe”。

  3. 从“文件”菜单中选择“添加服务”。

  4. 在地址框中键入 http://localhost:8080/hello,然后单击“确定”。

    提示

    确保服务正在运行,否则此步骤将失败。 如果已经更改了代码中的基址,则在此步骤中使用修改后的基址。

  5. 双击“我的服务项目”节点下的“SayHello”。 在“请求”列表的“值”列中,键入你的姓名,然后单击“调用”。

    此时“响应”列表中将显示一条答复消息。

示例

下面的示例创建 ServiceHost 对象以承载 HelloWorldService 类型的服务,然后调用 Open 上的 ServiceHost 方法。 在代码中提供基址,启用元数据发布,并使用默认终结点。

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

另请参阅