代码改变世界

WCF 第五章 行为 通过配置文件暴露一个服务行为

2010-12-13 17:59  DanielWise  阅读(657)  评论(0编辑  收藏  举报

列表5.25 实现了对在服务端配置中安装的软件授权码的一个验证行为。如果它不存在或者它不合法,服务将不会启动。它显示了服务运行时创建的用来验证配置信息的一个终结点行为。它也显示了当服务运行时创建时调用的一个行为扩展和扩展是如何将行为加入到服务运行时的。结果就是一个自定义行为在配置文件中(app.config 或者web.config)使用并被添加到服务运行时中以便于配置信息可以在服务启动时被验证。

  类myServiceBehavior实现了IServiceBehavior接口。类有两个属性,_EvaluationKey和_EvaluationType.myEndpointBehavior将这些值与预定义值比较。

  类myBehaviorExtensionElement 实现了IBehaviorExtensionElement接口。它定义了两个可以再配置文件中表现的[ConfigurationProperties]。它重载了BehaviorType和CreateBehavior方法以便于它可以返回同时在运行时启动时创建自定义行为myServiceBehavior。myServiceBehavior的构造函数有两个参数,每个属性一个,所以它可以执行验证操作。

列表5.25 在配置文件中暴露的终结点行为

 public class myServiceBehavior : IServiceBehavior
    {
        string _evaluationKey;
        string _evaluationType;
        public myServiceBehavior(string evaluationKey, string evaluationType)
        {
            _evaluationKey = evaluationKey;
            _evaluationType = evaluationType;
        }

        public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
        }

        public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            if ((_evaluationType == "Enterprise") & (_evaluationKey != "SuperSecretEvaluationKey"))
            {
                throw new Exception(string.Format("Invalid evaludation key.Type:{0}", _evaluationType));
            }
        }
    }
    public class myBehaviorExtensionElement : BehaviorExtensionElement
    {
        [ConfigurationProperty("EvaluationKey", DefaultValue = "", IsRequired = true)]
        public string EvaluationKey
        {
            get { return (string)base["evaluationKey"]; }
            set { base["evaluationKey"] = value; }
        }
        [ConfigurationProperty("EvaluationType", DefaultValue = "Enterprise", IsRequired = false)]
        public string EvaluationType
        {
            get { return (string)base["evaluationType"]; }
            set { base["evaluationType"] = value; }
        }

        public override Type BehaviorType
        {
            get
            {
                return typeof(myServiceBehavior);
            }
        }

        protected override object CreateBehavior()
        {
            return new myServiceBehavior(EvaluationKey, EvaluationType);
        }
    }
    [ServiceContract]
    public interface IStockService
    {
        [OperationContract]
        double GetPrice(string ticker);
    }

    public class StockService : IStockService
    {
        public double GetPrice(string ticker)
        {
            if (ticker == "MSFT")
            {
                return 94.85;
            }
            else
            {
                return 0.0;
            }
        }
    }

  列表5.26 显示了服务端的配置文件。在配置文件中添加了<behaviorExtension>,指向扩展实现。注意实现是强命名的,包括它的类型名和程序集信息(名称,版本,文化和公共密钥)。在这个例子中,程序集名字和存储扩展的DLL就是服务。

列表5.26 暴露一个终结点行为的配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors />
    <extensions>
      <behaviorExtensions>
        <add name="FreeTrial" type="Services.myBehaviorExtensionElement, Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2c0e9c165e34d972" />
      </behaviorExtensions>
    </extensions>
    <services>
      <service name="Services.StockService" behaviorConfiguration="customBehavior">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
            contract="Services.IStockService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/EssentialWCF" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="customBehavior">
          <FreeTrial EvaluationKey="SuperSecretEvaluationKey" EvaluationType="Enterprise"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>