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语言之捕捉信号
我们有时候需要在程序中做一些对于用户或内核发出的信号后的处理,如写回文件等善后处理的事情,或者直接忽略信号(当你按Ctrl+C时我压根不理你).下面是一段信号处理的代码(POSIX C): int c ...
- hdu 4324 拓扑排序
题意:给出一堆人的喜爱关系,判断有没有三角恋-_-|| 其实就是判断是否存在三条边的环. 一开始我是这么想的: 先拓扑排序,如果没有环那就直接No 如果有环?挑出环里的任意一个点(拓扑排序结束后不在拓 ...
- 使用Guava来计算笛卡尔积
以前做项目的时候计算笛卡尔积的时候,总是使用各种for循环来嵌套,最后往往在Sonar代码检查的时候总是会报警说for循环嵌套过深. 今天才知道Guava原来已经为我们提供了优雅的计算笛卡尔积的方法. ...
- HDU 1231 最大连续子序列(水题)
题目链接: 传送门 最大连续子序列 Time Limit: 1000MS Memory Limit: 32768 K Description 给定K个整数的序列{ N1, N2, ..., N ...
- python *args **kwargs
简单来说,当你传入的参数不能确定是几个的时候会用到 *args和**kwargs,这里星号后边只是个代号,你写成a也可以. 而这两者的区别是 如果是键值对就要用后者,反之前者就可以. 同时还可以用(a ...
- POJ1741:tree
传送门 时隔一个月再次写点分治,比上一次要深入理解很多了.(虽然代码还是写不熟 模板题,不多说 //POJ 1741 //by Cydiater //2016.9.22 #include <cs ...
- 百度云管家 5.3.6 VIP破解不限速版下载分享|百度云管家破解提速
百度云管家PC客户端v5.3.6绿色版本,属于VIP破解不限速版.百度网盘为您提供文件的网络备份.同步和分享服务.空间大.速度快.安全稳固,支持教育网加速,支持手机端.它支持便捷地查看.上传.下载云端 ...
- Navicat 的使用(一)
1.创建连接 主机名 : 可以不写名称随意 主机名/IP地址:localhost或者127.0.0.1 都是本机的意思 端口:默认3306 尽量不要改怕与其余端口重复,如有重名端口系统会报错 用户 ...
- C# Get/Post 模拟提交
public static string GetPage(string url, string encoding) { PublicVariables.NetworkConnection = fals ...
- iocp还是select
上一个项目libevent应该是select,现在libuv是iocp,都知道Windows下iocp比select效率高,boost asio 也是iocp,但具体使用select和iocp发现没有 ...