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 ...
随机推荐
- poj1113 凸包
result=对所有点凸包周长+pi*2*L WA了一次,被Pi的精度坑了 以后注意Pi尽可能搞精确一点.Pi=3.14还是不够用 Code: #include<vector> #incl ...
- 你应该了解Nginx的7个原因
Nginx ("engine x")是一个高性能的HTTP和反向代理服务器,也是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器 1 负载均衡实 ...
- zip压缩与解压缩示例
范例: zip命令可以用来将文件压缩成为常用的zip格式.unzip命令则用来解压缩zip文件. 1. 我想把一个文件abc.txt和一个目录dir1压缩成为yasuo.zip: # zip -r y ...
- Guava 集合框架
在本系列中我们首先来学习一些Guava的集合框架,也就是这个package:com.google.common.collect 在这个包下面有一些通用的集合接口和一些相关的类. 集合类型: BiM ...
- CentOs安装Scrapy出现error: Setup script exited with error: command ‘gcc’ failed with exit status 1错误解决方案
按照 http://www.1207.me/archives/209.html 的教程安装Scrapy出现了上述错误,但是本身机器已经有了gcc,所以应该是安装包的问题 百度又看到了同博客里的解决方案 ...
- C语言函数指针的用法
函数指针是一种在C.C++.D语言.其他类 C 语言和Fortran 2003中的指针.函数指针可以像一般函数一样,用于调用函数.传递参数.在如 C 这样的语言中,通过提供一个简单的选取.执行函数的方 ...
- vim配置有竖对齐线
https://github.com/lvxiaobo616/vim-indent-guides 参考 https://github.com/Yggdroot/indentLine 先安装 Yggdr ...
- 深入JVM-垃圾收集器常用的GC参数
1.与串行回收器相关的参数 -XX:+UseSerialGC:在新生代和老年代使用串行收集器 -XX:SurvivorRatio:设置eden区大小和survivor区大小的比例 -XX:Preten ...
- CSS的4种引入方式及优先级
第一:css的四种引入方式 1.行内样式 最直接最简单的一种,直接对HTML标签使用style="",例如: <p style="color:#F00; " ...
- qt5.4
rm -f libQt5Qml.so.5.4.0 libQt5Qml.so libQt5Qml.so.5 libQt5Qml.so.5.4g++ -Wl,-O1,--sort-common,--as- ...