WCF服务端基于配置的实现——拦截
2010-10-27 14:01
260 查看
如果说到拦截器,相信大家都不陌生,所有的AOP都依赖各种形式的拦截器。为了让WCF服务端的行为发生变化,这里要借助拦截器的力量。
那么,如何拦截操作哪?
如果熟悉WCF的话,那么,一定知道有这么一个接口:IOperationInvoker
这个接口的核心方法为:Invoke及其异步方法
而所有的OperationBehavior都实现了一个IOperationBehavior接口。
剩下来的问题是如何实现这两位主角。
为了简化期间,这里只考虑这样的情况:所有的操作只有一个输入值和一个输出值,以及只有同步操作。当然这里的一个输入/输出是指一个简单或复杂值,也就说,需要传多个值时,使用一个自定义类型来包裹这多个值。
简单的示意:
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
我们的Invoker目前什么好事情也没做(坏事倒是做了一桩,引入了不支持异步),别急,这个类还没完工哪。
再看看Behavior需要做什么:
好,拦截的外壳已经准备好了,来一个实例看看:
是不是很简单。
下篇预告
今天说了半天,都在说如何拦截的问题,还有个更大的问题如何路由,以及怎么实现动态路由,请看下篇。
问题:WCF里面如何创建一个拦截器?
事实上,WCF里面有很多种拦截器,分别用于拦截不同的信息。这里要改变的是方法的实现部分,因此,只要拦截WCF操作就可以达到目的。那么,如何拦截操作哪?
如果熟悉WCF的话,那么,一定知道有这么一个接口:IOperationInvoker
这个接口的核心方法为:Invoke及其异步方法
问题:如何把一个实现IOperationInvoker的实例注入WCF
仔细看一下MSDN,或者看reflector,就可以发现,所有实现IOperationInvoker的类型,几乎都是通过各种OperationBehavior加入的。而所有的OperationBehavior都实现了一个IOperationBehavior接口。
主角和设计约束
主角们在刚才的两个问题中已经全部登场了:IOperationInvoker和IOperationBehavior剩下来的问题是如何实现这两位主角。
为了简化期间,这里只考虑这样的情况:所有的操作只有一个输入值和一个输出值,以及只有同步操作。当然这里的一个输入/输出是指一个简单或复杂值,也就说,需要传多个值时,使用一个自定义类型来包裹这多个值。
实现
先说说实现IOperationInvoker,这里盗用一下MVC的概念,不妨将我们的实现控制器声明为:ControllerInvoker简单的示意:
internal sealed class ControllerInvoker
: IOperationInvoker
{
private readonly IOperationInvoker Inner;
public ControllerInvoker(IOperationInvoker inner)
{
Inner = inner;
}
public object[] AllocateInputs()
{
return Inner.AllocateInputs();
}
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
// do something before invoking
object result = Invoke(instance, inputs, out outputs);
// do something after invoking
return result;
}
public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
{
throw new NotSupportedException();
}
public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
{
throw new NotSupportedException();
}
public bool IsSynchronous
{
get { return true; }
}
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
我们的Invoker目前什么好事情也没做(坏事倒是做了一桩,引入了不支持异步),别急,这个类还没完工哪。
再看看Behavior需要做什么:
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class ControllerAttribute
: Attribute, IOperationBehavior
{
void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }
void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { }
void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
dispatchOperation.Invoker = new ControllerInvoker(dispatchOperation.Invoker);
}
void IOperationBehavior.Validate(OperationDescription operationDescription) { }
}
好,拦截的外壳已经准备好了,来一个实例看看:
[ServiceContract(Namespace="urn:Zhenway.Test")]
public interface ITest
{
[Controller]
[OperationContract]
TestResponse Test(TestRequest req);
}
是不是很简单。
下篇预告
今天说了半天,都在说如何拦截的问题,还有个更大的问题如何路由,以及怎么实现动态路由,请看下篇。
相关文章推荐
- WCF服务端基于配置的实现——路由
- WCF服务端基于配置的实现——预告篇
- 关于CAS服务端登录前ajax访问后台方法被拦截的配置-另外一种实现方式
- IT忍者神龟之基于CAS实现单点登录(SSO)之配置CAS服务端的数据库查询认证机制(一)
- 以配置的方式实现WCF的服务端和客户端的配置
- 【springboot】基于springboot运行原理实现springboot的自动配置
- Spring AOP(3)基于XML配置实现的示例
- 基于TCP协议的Socket通信 实现用户登录 以及服务端的相应
- WCF技术剖析之六:为什么在基于ASP.NET应用寄宿(Hosting)下配置的BaseAddress无效
- linux内核配置文件.config,基于s3c2410实现
- 基于corosync和pacemaker实现配置nginx的高可用集群
- wcf实现跨域访问所需的配置文件
- 基于纯Java代码的Spring容器和Web容器零配置的思考和实现(3) - 使用配置
- Spring(四)基于注解配置IOC容器&基于注解实现声明式事务
- 使用Cloudsim实现基于多维QoS的资源调度算法之中的一个:配置Cloudsim环境
- 基于Android RIL层实现来电拦截的技术原理(一)
- Spring学习(20)--- Schema-based AOP(基于配置的AOP实现) -- 配置切入点pointcut
- 利用WCF共享ASP.NET session实现WCF服务端验证
- wcf第2步之服务端标准配置文件
- 了解WCF的前世今生之实现服务端(一)