WCF自定义扩展,以实现aop!
使用自定义行为扩展 WCF
代码下载位置: ServiceStation2007_12.exe (165 KB)
Browse the Code Online
Figure 4 调度程序/代理扩展摘要| 阶段 | 侦听器接口 | 说明 |
|---|---|---|
| 参数检查 | IParameterInspector | 在调用前后调用,以检查和修改参数值。 |
| 消息格式化 | IDispatchMessageFormatter IClientFormatter | 调用以执行序列化和反序列化。 |
| 消息检查 | IDispatchMessageInspector IClientMessageInspector | 发送前或收到后调用,以检查和替换消息内容。 |
| 操作选择 | IDispatchOperationSelector IClientOperationSelector | 调用以选择要为给定的消息调用的操作。 |
| 操作调用程序 | IOperationInvoker | 调用以调用操作 |
[ServiceContract] public interface IZipCodeService {
[OperationContract]
string Lookup(string zipcode);
}
Figure 5 邮政编码验证参数检查器public class ZipCodeInspector : IParameterInspector { int zipCodeParamIndex; string zipCodeFormat = @"\d{5}-\d{4}"; public ZipCodeInspector() : this(0) { } public ZipCodeInspector(int zipCodeParamIndex) { this.zipCodeParamIndex = zipCodeParamIndex; } ... // AfterCall is empty public object BeforeCall(string operationName, object[] inputs) { string zipCodeParam = inputs[this.zipCodeParamIndex] as string; if (!Regex.IsMatch( zipCodeParam, this.zipCodeFormat, RegexOptions.None)) throw new FaultException( "Invalid zip code format. Required format: #####-####"); return null; } }
Figure 6 控制台跟踪消息检查器public class ConsoleMessageTracer : IDispatchMessageInspector, IClientMessageInspector { private Message TraceMessage(MessageBuffer buffer) { Message msg = buffer.CreateMessage(); Console.WriteLine("\n{0}\n", msg); return buffer.CreateMessage(); } public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { request = TraceMessage(request.CreateBufferedCopy(int.MaxValue)); return null; } public void BeforeSendReply(ref Message reply, object correlationState) { reply = TraceMessage(reply.CreateBufferedCopy(int.MaxValue)); } public void AfterReceiveReply(ref Message reply, object correlationState) { reply = TraceMessage(reply.CreateBufferedCopy(int.MaxValue)); } public object BeforeSendRequest(ref Message request, IClientChannel channel) { request = TraceMessage(request.CreateBufferedCopy(int.MaxValue)); return null; } }
Figure 7 邮政编码缓存操作调用程序public class ZipCodeCacher : IOperationInvoker { IOperationInvoker innerOperationInvoker; Dictionary<string, string> zipCodeCache = new Dictionary<string, string>(); public ZipCodeCacher(IOperationInvoker innerOperationInvoker) { this.innerOperationInvoker = innerOperationInvoker; } public object Invoke(object instance, object[] inputs, out object[] outputs) { string zipcode = inputs[0] as string; string value; if (this.zipCodeCache.TryGetValue(zipcode, out value)) { outputs = new object[0]; return value; } else { value = (string)this.innerOperationInvoker.Invoke( instance, inputs, out outputs); zipCodeCache[zipcode] = value; return value; } } ... // remaining methods elided // they simply delegate to innerOperationInvoker }
Figure 9 行为接口方法| 方法 | 说明 |
|---|---|
| 验证 | 仅在构建运行时前调用 — 允许您对服务说明执行自定义验证。 |
| AddBindingParameters | 在构建运行时的第一步时,且在构造底层通道前调用 — 允许添加参数,以影响底层通道堆栈。 |
| ApplyClientBehavior | 允许行为插入代理(客户端)扩展。请注意,IServiceBehavior 中不存在该方法。 |
| ApplyDispatchBehavior | 允许行为插入调度程序扩展。 |
Figure 8 行为类型| 作用域 | 接口 | 潜在影响 | |||
| 服务 | 终结点 | 约定 | 操作 | ||
| 服务 | IServiceBehavior | ✗ | ✗ | ✗ | ✗ |
| 终结点 | IEndpointBehavior | ✗ | ✗ | ✗ | |
| 约定 | IContractBehavior | ✗ | ✗ | ||
| 操作 | IOperationBehavior | ✗ |
Figure 10 操作行为示例public class ZipCodeValidation : Attribute, IOperationBehavior { public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { ZipCodeInspector zipCodeInspector = new ZipCodeInspector(); clientOperation.ParameterInspectors.Add(zipCodeInspector); } public void ApplyDispatchBehavior( OperationDescription operationDescription, DispatchOperation dispatchOperation) { ZipCodeInspector zipCodeInspector = new ZipCodeInspector(); dispatchOperation.ParameterInspectors.Add(zipCodeInspector); } ... // remaining methods empty } public class ZipCodeCaching : Attribute, IOperationBehavior { public void ApplyDispatchBehavior( OperationDescription operationDescription, DispatchOperation dispatchOperation) { dispatchOperation.Invoker = new ZipCodeCacher(dispatchOperation.Invoker); } ... // remaining methods empty }
Figure 11 终结点和服务行为示例public class ConsoleMessageTracing : Attribute, IEndpointBehavior, IServiceBehavior { void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.MessageInspectors.Add(new ConsoleMessageTracer()); } void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { endpointDispatcher.DispatchRuntime.MessageInspectors.Add( new ConsoleMessageTracer()); } ... // remaining methods empty void IServiceBehavior.ApplyDispatchBehavior( ServiceDescription desc, ServiceHostBase host) { foreach ( ChannelDispatcher cDispatcher in host.ChannelDispatchers) foreach (EndpointDispatcher eDispatcher in cDispatcher.Endpoints) eDispatcher.DispatchRuntime.MessageInspectors.Add( new ConsoleMessageTracer()); } ... // remaining methods empty }
ServiceHost host = new ServiceHost(typeof(ZipCodeService)); host.Description.Behaviors.Add(new ConsoleMessageTracing());
ServiceHost host = new ServiceHost(typeof(ZipCodeService)); foreach (ServiceEndpoint se in host.Description.Endpoints) se.Behaviors.Add(new ConsoleMessageTracing());
ZipCodeServiceClient client = new ZipCodeServiceClient(); client.ChannelFactory.Endpoint.Behaviors.Add( new ConsoleMessageTracing());
[ServiceContract] public interface IZipCodeService { [ZipCodeCaching] [ZipCodeValidation] [OperationContract] string Lookup(string zipcode); } [ConsoleMessageTracing] public class ZipCodeService : IZipCodeService { ... }
public class ConsoleMessageTracingElement : BehaviorExtensionElement { public override Type BehaviorType { get { return typeof(ConsoleMessageTracing); } } protected override object CreateBehavior() { return new ConsoleMessageTracing(); } }
Figure 13 配置行为<configuration> <system.serviceModel> <services> <service name="ZipCodeServiceLibrary.ZipCodeService" behaviorConfiguration="Default"> <endpoint binding="basicHttpBinding" contract="ZipCodeServiceLibrary.IZipCodeService"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="Default"> <serviceMetadata httpGetEnabled="true"/> <consoleMessageTracing/> </behavior> </serviceBehaviors> </behaviors> <extensions> <behaviorExtensions> <add name="consoleMessageTracing" type="Extensions. ConsoleMessageTracingElement, Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> </behaviorExtensions> </extensions> </system.serviceModel> </configuration>
Figure 14 行为配置选项| 行为类型 | 配置选项 | ||
| 属性 | 配置 | 显式 | |
| 服务 | ✗ | ✗ | ✗ |
| 终结点 | ✗ | ✗ | |
| 约定 | ✗ | ✗ | |
| 操作 | ✗ | ✗ |
public class NoBasicEndpointValidator : Attribute, IServiceBehavior { #region IServiceBehavior Members public void Validate(ServiceDescription desc, ServiceHostBase host) { foreach (ServiceEndpoint se in desc.Endpoints) if (se.Binding.Name.Equals("BasicHttpBinding")) throw new FaultException( "BasicHttpBinding is not allowed"); } ... //remaining methods empty }
WCF自定义扩展,以实现aop!的更多相关文章
- SharePoint 2013 自定义扩展菜单
在对SharePoint进行开发或者功能扩展的时候,经常需要对一些默认的菜单进行扩展,以使我们开发的东西更适合SharePoint本身的样式.SharePoint的各种功能菜单,像网站设置.Ribbo ...
- SharePoint 2013 自定义扩展菜单(二)
接博文<SharePoint 2013 自定义扩展菜单>,多加了几个例子,方便大家理解. 例七 列表设置菜单扩展(listedit.aspx) 扩展效果 XML描述 <CustomA ...
- Jquery自定义扩展方法(二)--HTML日历控件
一.概述 研究了上节的Jquery自定义扩展方法,自己一直想做用jquery写一个小的插件,工作中也用到了用JQuery的日历插件,自己琢磨着去造个轮子--HTML5手机网页日历控件,废话不多说,先看 ...
- Silverlight实例教程 - 自定义扩展Validation类,验证框架的总结和建议(转载)
Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...
- jQuery 自定义扩展,与$冲突处理
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件
需求 SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件 扩展 class SparkContext(pyspark.SparkContext): def ...
- 基于 HtmlHelper 的自定义扩展Container
基于 HtmlHelper 的自定义扩展Container Intro 基于 asp.net mvc 的权限控制系统的一部分,适用于对UI层数据呈现的控制,基于 HtmlHelper 的扩展组件 Co ...
- 第十三节:HttpHander扩展及应用(自定义扩展名、图片防盗链)
一. 自定义扩展名 1. 前言 凡是实现了IHttpHandler接口的类均为Handler类,HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...
- Asp.Net Mvc 自定义扩展
目录: 自定义模型IModelBinder 自定义模型验证 自定义视图引擎 自定义Html辅助方法 自定义Razor辅助方法 自定义Ajax辅助方法 自定义控制器扩展 自定义过滤器 自定义Action ...
随机推荐
- 数据结构算法C语言实现(一)---2.2线性表的顺序表示和实现
注意: 虽然是用C语言实现,但是考虑到使用了一个C++的特性----引用以简化代码,所以所有的代码均以cpp作为后缀,用g++编译(以后不做说明). g++版本: 一.简述 本节主要讲述线性表的顺序实 ...
- C#12种顺序排序
这篇主要写关于顺序排序的十二种算法,也是我有关算法的第一帖.主要是写,对每种算法的理解与测试. 速度测试,主要根据一千.一万.五万.百万这 四种.速度纪录还是用Stopwatch 这个类.使用随机数R ...
- Linux之:Ubuntu速学笔记(2)
撰写日期:2016-7-3 18:20:39 基本内容包括:Flash player安装.编译安装PHP.写个简单的PHP程序:Java程序(Java需要使用“javac”命令编译一下才能执行) 一. ...
- Post请求和get请求乱码方式解决
POST提交,提交页面显示中文乱码 //设置请求的编码格式 request.setCharacterEncoding("utf-8"); //设置响应的编码格式,与第一句的编码格式 ...
- Java中StringBuilder的清空方法比较
StringBuilder 没有提供clear或empty方法.清空有3种方法:1)使用delete2)新生成一个,旧的由系统自动回收3)使用setLength 将三种方法循环1000万次,代码: p ...
- 【项目】iOS - 使用UIWebView占用内存过大
通过其他博主介绍的解决这个问题的博客: http://blog.techno-barje.fr//post/2010/10/04/UIWebView-secrets-part1-memory-leak ...
- ubuntu14.04设置开机亮度
1 查看自己的系统亮度的最大值: cd /sys/class/backlight 笔记本的显卡型号不同->亮度调节文件夹名会不同. 2 我的是intel_backlight cd intel_b ...
- 深入理解javascript中执行环境(作用域)与作用域链
深入理解javascript中执行环境(作用域)与作用域链 相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行 ...
- springMVC的注解详解
springmvc常用注解标签详解 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业 ...
- java的对象的总结:(PO,VO,DAO,BO,POJO)
一.PO:persistant object 持久对象,可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合.PO中应该不包含任何对数 ...