WCF标准端点的高级应用

在Windows Communication Foundation (WCF)中,标准端点是一个强大的特性,它允许开发者以一种更简洁的方式定义服务端点。通过标准端点,可以指定一个特殊的“类型”名称,它会自动配置端点的地址、绑定、契约、绑定配置和端点行为。这种特性在需要在多个项目中重复使用相同配置的端点时尤其有用。

标准端点的基本概念

WCF中,通常需要为端点指定地址、绑定和契约(ABC)。如果需要对端点进行额外的配置,比如改变绑定配置或端点行为,还需要添加更多的配置。虽然可以使用WCF 4的默认配置特性,但如果有两组常见的设置,不能设置两个默认值,这样就回到了起点。

标准端点改变了定义端点的方式。通过标准端点,只需要在端点中指定一个特殊的“类型”名称,它会自动设置端点的地址、绑定、契约、绑定配置和端点行为。例如,如果定义了以下端点:

<endpoint address="mex" kind="mexEndpoint" />

上述端点将自动使用 mexHttpBindingIMetadataExchange 契约。如果定义了以下端点:

<endpoint code="web" kind="webHttpEndpoint" contract="MyNS.IMyContract" />

将得到一个使用 webHttpBinding 的端点,并自动获得 webHttp 端点行为。

创建自定义标准端点

虽然这已经很不错了,但标准端点的真正用途在于创建自己的标准端点。想象一下,是组织中的基础设施团队的一员,需要向开发团队解释他们在项目中应该使用哪种端点配置。一种方法是发送一份备忘录给所有开发团队,希望每个人都严格按照指示操作。另一种方法是创建自己的标准端点,包含所有上述配置,然后发送给开发团队使用。

首先,需要创建自定义端点:

public class CompanyNameStandardEndpoint : ServiceEndpoint { private bool _isSecured; public CompanyNameStandardEndpoint(ContractDescription contract) : base(contract) { this.Binding = new NetTcpBinding(); ResetBindingConfiguration(this.Binding); this.IsSystemEndpoint = false; } public bool IsSecured { get { return _isSecured; } set { _isSecured = value; if (_isSecured) { (this.Binding as NetTcpBinding).Security.Mode = SecurityMode.Transport; } else { (this.Binding as NetTcpBinding).Security.Mode = SecurityMode.None; } } } private void ResetBindingConfiguration(dynamic binding) { binding.SendTimeout = TimeSpan.FromMinutes(5); binding.MaxReceivedMessageSize = Int32.MaxValue; binding.MaxBufferSize = Int32.MaxValue; } }

在代码中,第8行确保端点将使用 NetTcpBinding。第9行将调用一个初始化绑定设置的方法(第36-41行)。

注意:ResetBindingConfiguration 方法接收一个动态对象,因为出于某种原因,一些绑定属性(如 MaxReceivedMessageSizeMaxBufferSize)是在每个绑定中定义的,而不是在基础 Binding 类中定义的。动态类型将允许稍后更改代码以支持TCP和HTTP绑定,而不需要为重载复制方法。

第10行指定这是一个用户定义的端点,而不是系统端点。第13-32行负责处理用户的选择,根据用户的选择将安全模式更改为 TransportNone

在代码中添加自定义端点

现在,有一个新的标准端点,它初始化绑定到 NetTcpBinding,设置超时和消息大小,并知道根据用户的选择设置安全性。现在可以通过调用以下代码将此端点添加到服务中:

CompanyNameStandardEndpoint newEndpoint = new CompanyNameStandardEndpoint(ContractDescription.GetContract(typeof(IService1))); newEndpoint.IsSecured = false; newEndpoint.Address = new EndpointAddress(tcpBaseAddress + "companyUnsecured"); host.AddServiceEndpoint(newEndpoint);

配置文件中添加端点配置

要能够在配置文件中添加此端点配置,需要添加一些样板代码:

public class CompanyNameStandardEndpointCollectionElement : StandardEndpointCollectionElement<CompanyNameStandardEndpoint, CompanyNameStandardEndpointElement> { } public class CompanyNameStandardEndpointElement : StandardEndpointElement { protected override ServiceEndpoint CreateServiceEndpoint(ContractDescription contractDescription) { return new CompanyNameStandardEndpoint(contractDescription); } public bool IsSecured { get { return (bool)base["isSecured"]; } set { base["isSecured"] = value; } } protected override ConfigurationPropertyCollection Properties { get { ConfigurationPropertyCollection properties = base.Properties; properties.Add(new ConfigurationProperty("isSecured", typeof(bool), false, ConfigurationPropertyOptions.None)); return properties; } } protected override Type EndpointType { get { return typeof(CompanyNameStandardEndpoint); } } protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ServiceEndpointElement serviceEndpointElement) { CompanyNameStandardEndpoint customEndpoint = (CompanyNameStandardEndpoint)endpoint; customEndpoint.IsSecured = this.IsSecured; } protected override void OnApplyConfiguration(ServiceEndpoint endpoint, ChannelEndpointElement channelEndpointElement) { CompanyNameStandardEndpoint customEndpoint = (CompanyNameStandardEndpoint)endpoint; customEndpoint.IsSecured = this.IsSecured; } protected override void OnInitializeAndValidate(ServiceEndpointElement serviceEndpointElement) { } protected override void OnInitializeAndValidate(ChannelEndpointElement channelEndpointElement) { } }

上述代码是一个基本的配置元素代码。最重要的部分是第13-17行,需要重复创建的每个属性在自定义标准元素中的映射(用于XML和CLR之间的映射),以及第24行,需要添加所有可以在配置文件中设置的属性,以便可以验证配置。

在配置文件中使用新端点类型

创建上述代码后,需要再执行一个步骤才能在配置中使用新的端点类型——需要告诉WCF有一个新的服务端点。为此,需要在 <system.serviceModel> 部分添加以下XML:

<extensions> <endpointExtensions> <add name="companyNameEndpoint" type="TestWcfStandardEndpoints.CompanyNameStandardEndpointCollectionElement, TestWcfStandardEndpoints" /> </endpointExtensions> </extensions>

注意:在MSDN上,可以找到关于标准端点的良好解释,但扩展配置部分是不正确的,上述配置是正确的(正确的元素在 <extensions><endpointExtensions> 而不是文章中出现的 <standardEndpointExtensions>)。

声明和配置新端点

现在,已经准备好声明新端点并配置它们:

<services> <service name="TestWcfStandardEndpoints.Service1"> <endpoint binding="basicHttpBinding" contract="TestWcfStandardEndpoints.IService1" /> <endpoint address="mex" kind="mexEndpoint" /> <endpoint address="companySecured" kind="companyNameEndpoint" endpointConfiguration="securedEndpoint" contract="TestWcfStandardEndpoints.IService1" /> </service> </services> <standardEndpoints> <companyNameEndpoint> <standardEndpoint isSecured="true" name="securedEndpoint" /> </companyNameEndpoint> </standardEndpoints>

在第7-10行中,定义了具有新“类型”的端点(第9行)并指定了配置端点其余部分的位置(第10行)。第14-18行包含了创建的标准端点的配置。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485