在代码中配置 WCF 服务

Windows Communication Foundation (WCF) 使开发人员能够使用配置文件或代码配置服务。 当部署之后需要对服务进行配置时,配置文件十分有用。 在使用配置文件时,IT 专业人员只需要更新配置文件,无需重新编译。 不过,配置文件可能十分复杂,难以维护。 不支持对配置文件进行调试,并且将按名称来引用配置元素,这使得配置文件的创作易于出错且较为困难。 通过 WCF,你还可以使用代码来配置服务。 在早期版本的 WCF(4.0 及更早版本)中,使用代码来配置服务在自托管方案中十分简单,通过 ServiceHost 类,可以在调用 ServiceHost.Open 之前配置终结点和行为。 但是,在 Web 承载方案中,你不具备针对 ServiceHost 类的直接访问权限。 若要配置 Web 承载的服务,你需要创建 System.ServiceModel.ServiceHostFactory,后者会创建 ServiceHostFactory 并执行任何所需的配置。 从 .NET Framework 4.5 起,WCF 提供了一种使用代码来配置自托管服务和 Web 托管服务的更简单的方法。

Configure 方法

只需在您的服务实现类中使用以下签名定义名为 Configure 的公共静态方法:

public static void Configure(ServiceConfiguration config)

Configure 方法采用 ServiceConfiguration 实例,使开发者可以添加终结点和行为。 在打开服务主机之前,由 WCF 调用此方法。 定义后,将忽略 app.config 或 web.config 文件中指定的任何服务配置设置。

下面的代码段阐释如何定义 Configure 方法和添加服务终结点、终结点行为以及服务行为:

public class Service1 : IService1
    {
        public static void Configure(ServiceConfiguration config)
        {
            ServiceEndpoint se = new ServiceEndpoint(new ContractDescription("IService1"), new BasicHttpBinding(), new EndpointAddress("basic"));
            se.Behaviors.Add(new MyEndpointBehavior());
            config.AddServiceEndpoint(se);

            config.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
            config.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });
        }

        public string GetData(int value)
        {
            return $"You entered: {value}";
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
    }

要为服务启用协议(如 https),可以显式添加使用协议的终结点,也可以通过调用 ServiceConfiguration.EnableProtocol(Binding) 自动添加终结点,这样可为与协议兼容的每个基址和定义的每个服务协定添加终结点。 下面的代码演示如何使用 ServiceConfiguration.EnableProtocol 方法:

public class Service1 : IService1
{
    public string GetData(int value);
    public static void Configure(ServiceConfiguration config)
    {
        // Enable "Add Service Reference" support
       config.Description.Behaviors.Add( new ServiceMetadataBehavior { HttpGetEnabled = true });
       // set up support for http, https, net.tcp, net.pipe
       config.EnableProtocol(new BasicHttpBinding());
       config.EnableProtocol(new BasicHttpsBinding());
       config.EnableProtocol(new NetTcpBinding());
       config.EnableProtocol(new NetNamedPipeBinding());
       // add an extra BasicHttpBinding endpoint at http:///basic
       config.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(),"basic");
    }
}

<protocolMappings> 节中的设置仅在没有以编程方式向 ServiceConfiguration 添加应用程序终结点时才使用。你可以选择通过调用 LoadFromConfiguration 从默认应用程序配置文件加载服务配置,然后更改设置。 LoadFromConfiguration() 类还允许您从集中式配置加载配置。 下面的代码演示如何实现这一点:

public class Service1 : IService1
{
    public void DoWork();
    public static void Configure(ServiceConfiguration config)
    {
          config.LoadFromConfiguration(ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = @"c:\sharedConfig\MyConfig.config" }, ConfigurationUserLevel.None));
    }
}

重要

请注意,LoadFromConfiguration 会忽略 <system.serviceModel> 的 <service> 标记内的 <host> 设置。 从概念上讲,<host> 针对的是主机配置而不是服务配置,它会在 Configure 方法执行之前加载。

另请参阅