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