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 ...
随机推荐
- Ajax请求接口加密研究(针对网页前端的接口安全加密机制研究)
通常我们在h5前端调用后台接口时,一般是ajax,那么接口的安全成了一个问题. 这里可以肯定的说,前端调用的接口一定要验证! 然后剖析了微信网页版.京东网页版这些,也都是通过接口的形势绑定数据,所以在 ...
- glibc resolv/res_send.c getaddrinfo() buffer stack smash when dealing malformation big DNS Response Package
catalogue . 漏洞简述 . 调试环境搭建 . 漏洞利用 . 漏洞分析 . 缓解修复方案 1. 漏洞简述 0x1: 函数调用顺序 getaddrinfo (getaddrinfo.c) -&g ...
- string字符串的一系列操作
IndexOf() 查找字串中指定字符或字串首次出现的位置,返首索引值,如: str1.IndexOf("字"): //查找“字”在str1中的索引值(位置) str1.Index ...
- jpa和hibernate注解
http://www.objectdb.com/api/java/jpa/JoinColumns 用hibernate和jpa annotation 大概一年多了,今天闲来无事,对他们关联关系元数据写 ...
- HDU 5726 GCD
传送门 GCD Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem ...
- Centos7更新firefox
1.用你本地的旧版 firefox,访问http://www.firefox.com.cn,下载Linux版本的Firefox. 2.进入存放下载文件(Firefox-latest-x86_64.ta ...
- appium+java+junit demo运行
对java熟悉一些,所以想用java把appium给做起来.今天用myeclipse给环境和Demo弄了一下,网上没有一篇全套资料的. 各块环境的搭建: 1.安装appium客户端,省略下载和安装步骤 ...
- POJ - 2253 Frogger(Dijkstra变形题)
题意: 题目撰写者的英语真是艰难晦涩,看了别人题解,才知道这题题意. 两个forger 一个froger 要蹦到另外一个froger处,他们的最短距离是这样定义的 : The frog distanc ...
- 软件工程个人作业-Week2
第一部分 调研, 评测 必应词典客户端版本:安卓版5.2.2 bug描述一:在学习页面点击“单词挑战”或“我爱说英语”会弹出“加载失败,请稍后重试”,无论点击多少次都加载不出来. bug描述二:在未 ...
- SSH 学习总结-01 SSH整合环境
一 Struts2+Spring3+Hibernate4+Maven 整合环境 1 开发工具 1)JDK下载地址:http://www.oracle.com/technetwork/java/java ...