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(); }
}
}
Extending WCF using IServiceBehavior, IOperationBehavior, and IParameterInspector的更多相关文章
- Wcf实现IServiceBehavior拓展机制
IServiceBehavior接口 描述:提供一种在整个服务内修改或插入自定义拓展机制: 命名空间: System.ServiceModel.Description程序集: System.Ser ...
- 真实世界:使用WCF扩展记录服务调用时间
WCF 可扩展性 WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Layer 之上还提供了一个高级运行时,主要是针对应用程序开发人员.在 WCF 文档中,它常被称为服 ...
- WCF扩展
WCF 可扩展性 WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Layer 之上还提供了一个高级运行时,主要是针对应用程序开发人员.在 WCF 文档中,它常被称为服 ...
- 使用WCF扩展记录服务调用时间
随笔- 64 文章- 0 评论- 549 真实世界:使用WCF扩展记录服务调用时间 WCF 可扩展性 WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Lay ...
- WCF扩展记录服务调用时间
WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Layer 之上还提供了一个高级运行时,主要是针对应用程序开发人员.在 WCF 文档中,它常被称为服务模型层(Serv ...
- WCF笔记
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iparameterinspector.aftercall ...
- 转 使用IParameterInspector, IOperationBehavior,Attribute(参数检查器、操作行为接口和标签)扩展WCF操作行为
public class EntryIdInspector : IParameterInspector { public int intParamIndex { get; set; } string ...
- IServiceBehavior IContractBehavior IEndpointBehavior IOperationBehavior
using System; using System.Collections.ObjectModel; using System.Reflection; using System.ServiceMod ...
- WCF自定义扩展,以实现aop!
引用地址:https://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx 使用自定义行为扩展 WCF Aaron Skonnard 代码下载位置: S ...
随机推荐
- Java Web J2EE下的两大框架SSH和SSM对比
当下流行的两种企业开发MVC开源框架,是我们Java程序猿必备知识能力.MVC,即模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界 ...
- 算法习题---5.6团体队列(Uva540)
一:题目 有t个队伍的人正在排队,每次新来一个人,如果他有队友在排队,那他可以插队,直接排到他的队伍的末尾.如果没有队伍在前面,那么他直接排在长队的末尾 ENQUEUE x 将编号x的队员入队 DEQ ...
- Day1作业1:登陆接口(加入日志、注册功能)
流程图如下: 最先考虑使用python中的list,以能取到user_list中的用户信息,但中途发现没有比较好的方法截取取密码,还是新手的缘故,最终选择了使用dict,以方便截取用户名以及相应的密码 ...
- Flink FileSink 自定义输出路径——BucketingSink
今天看到有小伙伴在问,就想着自己实现一下. 问题: Flink FileSink根据输入数据指定输出位置,比如讲对应日期的数据输出到对应目录 输入数据: 20190716 输出到路径 20190716 ...
- 比较两个数组的键名,并返回交集:array_intersect_key
$a1=array("a"=>"red","b"=>"green","c"=>&q ...
- 【prometheus 抓取源】
配置prometheus从prometheus爬取数据 prometheus提供了下面这个端口来让其他prometheus来抓取(scrape)自己的时序数据: http://prometheus_i ...
- 【docker 使用】创建镜像docker build
创建镜像命令 docker build -t [镜像name]:[镜像tag] -f [dockerfile路径] [资源目录] 执行该命令后,docker会将[资源目录]打包,之后在dockerfi ...
- DevOps - DevOps精要 - 溯源
1 - DevOps的含义 DevOps涉及领域广泛,其含义因人而异,在不同的理解和需求场景下,有着不同的实践形式. DevOps可以理解为是一个职位.一套工具集合.一组过程与方法.一种组织形式与文化 ...
- C++ 宏和模板简介
参考<21天学通C++>第14章节,对C++中的宏和模板进行了学习,总结起来其主要内容如下: (1) 预处理器简介 (2) 关键字#define与宏 (3) 模板简介 (4) 如何编写函数 ...
- matlab绘制直方图的方法
直接上代码,利用hist绘制频次直方图和频率直方图... %rand Fs=1000;N=10000; t=0:1/Fs:(N-1)/Fs; X1=rand(1,length(t)); subplot ...