Extending WCF using IServiceBehavior, IOperationBehavior, and IParameterInspector

[ServiceContract(Name = "PasswordGenerator")]
public interface IPasswordGenerator
{
    [OperationContract(Name = "GeneratePassword")]
    string GeneratePassword();
    [OperationContract(Name="ParameterizedPasswordGenerator")]
    string GeneratePassword(int length);
}

public class PasswordGenerator:IPasswordGenerator
{
    [OperationBehavior()]
    public string GeneratePassword()
    {
        return "You called GeneratePassword()";
    }



    [OperationBehavior()]
    public string GeneratePassword(int length)
    {
        return "You called GeneratePassword(int length) overload";
    }
}

  

static void Main(string[] args)
{
    ServiceEndpoint serviceEndpoint;
    Uri basePipeAddress = new Uri(@"net.Pipe://localhost/Password/Mine");
    using (ServiceHost host = 
             new ServiceHost(typeof(Password.PasswordGenerator), basePipeAddress))
    {
        serviceEndpoint = host.AddServiceEndpoint(typeof(
            Password.IPasswordGenerator), new NetNamedPipeBinding(), string.Empty);
        host.Open();

        using (var factory = new 
           ChannelFactory<password.passwordgenerator>(new NetNamedPipeBinding()))
        {
            var proxy = factory.CreateChannel(serviceEndpoint.Address);
            proxy.GeneratePassword();
            proxy.GeneratePassword(1500);
            factory.Close();
        }
        host.Close();
    }
}

  

public static class Logger
{
    private static void Log(string message)
    {
        try
        {
            using (var stream = new StreamWriter(@"G:\log.log", true))
            {
                stream.WriteLine(message);

                stream.Flush();
                stream.Close();
            }
        }
        catch (Exception)
        {
            
            
        }
    }
    public static void Log(string className, string methodName, string parameter)
    {
        Log(string.Format("Class {0} called method {1} with parameter {2} @ {3}", 
               className, methodName, parameter, DateTime.Now));
    }
    
}  

  First Extension

public class MyServiceBehaviorAttribute : Attribute, IServiceBehavior
{
 
    public void AddBindingParameters(ServiceDescription serviceDescription, 
      ServiceHostBase serviceHostBase, 
      Collection<ServiceEndpoint> endpoints, 
      BindingParameterCollection bindingParameters)
    {
        Logger.Log("MyServiceBehaviorAttribute", 
          "AddBindingParameters", serviceDescription.Name);
    }
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, 
                ServiceHostBase serviceHostBase)
    {
        Logger.Log("MyServiceBehaviorAttribute", 
          "ApplyDispatchBehavior", serviceDescription.Name);
    }
    public void Validate(ServiceDescription serviceDescription, 
                         ServiceHostBase serviceHostBase)
    {
        Logger.Log("MyServiceBehaviorAttribute", 
          "Validate", serviceDescription.Name);
    }
} 

  Second Extension

public class MyOperationBehavior:Attribute, IOperationBehavior 
{
    public void AddBindingParameters(OperationDescription operationDescription, 
      System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
        Logger.Log("MyOperationBehavior", 
          "AddBindingParameters", operationDescription.Name);
    }

    public void ApplyClientBehavior(OperationDescription operationDescription, 
      System.ServiceModel.Dispatcher.ClientOperation clientOperation)
    {
        clientOperation.ParameterInspectors.Add(new MyParameterInspector());
        Logger.Log("MyOperationBehavior", 
          "ApplyClientBehavior", operationDescription.Name);
    }

    public void ApplyDispatchBehavior(OperationDescription operationDescription, 
      System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
    {
        dispatchOperation.ParameterInspectors.Add(new MyParameterInspector());
        Logger.Log("MyOperationBehavior", 
          "ApplyDispatchBehavior", operationDescription.Name);
    }

    public void Validate(OperationDescription operationDescription)
    {
        Logger.Log("MyOperationBehavior", "Validate", operationDescription.Name);
    }
}

  Third Extension

class MyParameterInspector:IParameterInspector 
{
    public void AfterCall(string operationName, object[] outputs, 
                          object returnValue, object correlationState)
    {
        Logger.Log("MyParameterInspector", "AfterCall", operationName);
    }

    public object BeforeCall(string operationName, object[] inputs)
    {
        Logger.Log("MyParameterInspector", "BeforeCall", operationName);
        return null;
    }
}

  

[__strong__][MyServiceBehaviorAttribute()]
public class PasswordGenerator:IPasswordGenerator
{
    [OperationBehavior(),MyOperationBehavior]
    public string GeneratePassword()
    {
        return "You called GeneratePassword()";
    }

    [OperationBehavior()]
    [MyOperationBehavior]
    public string GeneratePassword(int length)
    {
        return "You called GeneratePassword(int length) overload";
    } 

  

 

 

---------------------------------------------------------------------------------------------------------------------

 

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Reflection;

namespace AOPAndWCF
{
    class MyParameterInspector: IOperationBehavior, IParameterInspector
    {
        #region IOperationBehavior Members
        /// <summary>
        /// 
        /// </summary>
        /// <param name="operationDescription"></param>
        /// <param name="bindingParameters"></param>
        public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="operationDescription"></param>
        /// <param name="clientOperation"></param>
        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
           
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="operationDescription"></param>
        /// <param name="dispatchOperation"></param>
        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            dispatchOperation.ParameterInspectors.Add(this);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="operationDescription"></param>
        public void Validate(OperationDescription operationDescription)
        {
           
        }

        #endregion

        
        /// <summary>
        /// 调用方法后 输出结果值
        /// </summary>
        /// <param name="operationName"></param>
        /// <param name="outputs"></param>
        /// <param name="returnValue"></param>
        /// <param name="correlationState"></param>
        public void AfterCall(string operationName, object[] outputs, object  returnValue, object correlationState)
        {
            Console.WriteLine("*************返回操作名称:" + operationName+"*************");
            Console.WriteLine("*************返回操作编号:" + correlationState.ToString() + "**************");
            for (int i = 0; i < outputs.Length; i++)
            {

                Type T = outputs[i].GetType();
                Console.WriteLine("返回操作参数" + i.ToString() + "  类型为:" + T.ToString());
                Console.WriteLine("返回操作参数" + i.ToString() + "  ToString为:" + outputs[i].ToString());
                Console.WriteLine("返回操作参数" + i.ToString() + "  属性:");
                PropertyInfo[] PIs = T.GetProperties();
                foreach (PropertyInfo PI in PIs)
                {
                    Console.Write(PI.Name + ":");
                    Console.WriteLine(PI.GetValue(outputs[i], null));
                }


            }

            Type Treturn = returnValue.GetType();
            Console.WriteLine("操作返回值" + "  类型为:" + Treturn.ToString());
            Console.WriteLine("操作返回值" + "  ToString为:" + Treturn.ToString());
            Console.WriteLine("操作返回值"  + "  属性:");

            if (Treturn.ToString() != "System.String")
            {
                PropertyInfo[] PIreturns = Treturn.GetProperties();
                foreach (PropertyInfo PI in PIreturns)
                {
                    Console.Write(PI.Name + ":");
                    Console.WriteLine(PI.GetValue(returnValue, null));
                }
            }

          
        }
        /// <summary>
        /// 调用方法前 输出参数值
        /// </summary>
        /// <param name="operationName"></param>
        /// <param name="inputs"></param>
        /// <returns></returns>
        public object BeforeCall(string operationName, object[] inputs)
        {
            Guid guid = Guid.NewGuid();

            Console.WriteLine("*************调用操作名称:" + operationName+"**************");
            Console.WriteLine("*************调用操作编号:" + guid.ToString () + "**************");
            for (int i = 0; i < inputs.Length ; i++)
			{
			
             Type T = inputs[i] .GetType ();
             Console.WriteLine("操作参数"+i.ToString ()+"  类型为:"+T.ToString ());
             Console.WriteLine("操作参数" + i.ToString() + "  ToString为:" + inputs[i].ToString());
             Console.WriteLine("操作参数" + i.ToString() + "  属性:");
             PropertyInfo [] PIs =  T.GetProperties();
             foreach (PropertyInfo PI in PIs)
             {             
               Console.Write (     PI.Name +":");
                Console.WriteLine (PI.GetValue(inputs[i], null));
             }

            }
            return guid;
        }


    }
}

  

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel ;
using System.ServiceModel.Description;
namespace AOPAndWCF
{
   public  class MyServiceHost:ServiceHost 
    {
         /// <summary>
       /// 构造函数
       /// </summary>
       /// <param name="serviceType">服务类型</param>
       /// <param name="baseAddresses">基地址</param>
        public MyServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { }

       /// <summary>
       /// 应用配置文件设置
       /// </summary>
       protected override void ApplyConfiguration()
       {
           base.ApplyConfiguration();
           //加入参数检查服务
           addguidvalidation();

       }
    
       /// <summary>
       ///加入参数检查服务
       /// </summary>
       private void addguidvalidation()
       {
           //加入参数检查服务
           int endpointscount = this.Description.Endpoints.Count;
           MyParameterInspector mypi = new MyParameterInspector();
           for (int i = 0; i < endpointscount; i++)
           {
               if (this.Description.Endpoints[i].Contract.Name != "IMetadataExchange")
               {
                   int Operationscount = this.Description.Endpoints[i].Contract.Operations.Count;
                   for (int j = 0; j < Operationscount; j++)
                   {
                       this.Description.Endpoints[i].Contract.Operations[j].Behaviors.Add(mypi);
                   }
               }
           }
       }

    }
}

  

using System;
using System.Collections.Generic;
using System.Text;

namespace AOPAndWCF
{
    class Program
    {
        static void Main(string[] args)
        {
            MyServiceHost msh = new MyServiceHost(typeof(WcfServiceLibrary.Service1 ));
            msh.Open();
            Console.WriteLine ("服务已开启,回车关闭服务");
            Console.ReadLine();
            msh.Close();


        }
    }
}

  

 

posted @ 2017-04-26 16:52  hi.....  阅读(289)  评论(0编辑  收藏  举报