如果说到拦截器,相信大家都不陌生,所有的AOP都依赖各种形式的拦截器。为了让WCF服务端的行为发生变化,这里要借助拦截器的力量。
问题:WCF里面如何创建一个拦截器?
事实上,WCF里面有很多种拦截器,分别用于拦截不同的信息。这里要改变的是方法的实现部分,因此,只要拦截WCF操作就可以达到目的。
那么,如何拦截操作哪?
如果熟悉WCF的话,那么,一定知道有这么一个接口:IOperationInvoker
这个接口的核心方法为:Invoke及其异步方法
问题:如何把一个实现IOperationInvoker的实例注入WCF
仔细看一下MSDN,或者看reflector,就可以发现,所有实现IOperationInvoker的类型,几乎都是通过各种OperationBehavior加入的。
而所有的OperationBehavior都实现了一个IOperationBehavior接口。
主角和设计约束
主角们在刚才的两个问题中已经全部登场了:IOperationInvoker和IOperationBehavior
剩下来的问题是如何实现这两位主角。
为了简化期间,这里只考虑这样的情况:所有的操作只有一个输入值和一个输出值,以及只有同步操作。当然这里的一个输入/输出是指一个简单或复杂值,也就说,需要传多个值时,使用一个自定义类型来包裹这多个值。
实现
先说说实现IOperationInvoker,这里盗用一下MVC的概念,不妨将我们的实现控制器声明为:ControllerInvoker
简单的示意:
1: internal sealed class ControllerInvoker
2: : IOperationInvoker 3: { 4: 5: private readonly IOperationInvoker Inner;
6: 7: public ControllerInvoker(IOperationInvoker inner)
8: { 9: Inner = inner; 10: } 11: 12: public object[] AllocateInputs()
13: {14: return Inner.AllocateInputs();
15: } 16: 17: public object Invoke(object instance, object[] inputs, out object[] outputs)
18: {19: // do something before invoking
20: object result = Invoke(instance, inputs, out outputs);
21: // do something after invoking
22: return result;
23: } 24: 25: public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
26: {27: throw new NotSupportedException();
28: } 29: 30: public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
31: {32: throw new NotSupportedException();
33: } 34: 35: public bool IsSynchronous
36: {37: get { return true; }
38: } 39: }我们的Invoker目前什么好事情也没做(坏事倒是做了一桩,引入了不支持异步),别急,这个类还没完工哪。
再看看Behavior需要做什么:
1: [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
2: public sealed class ControllerAttribute
3: : Attribute, IOperationBehavior 4: { 5: 6: void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }
7: 8: void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { }
9: 10: void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
11: {12: dispatchOperation.Invoker = new ControllerInvoker(dispatchOperation.Invoker);
13: } 14: 15: void IOperationBehavior.Validate(OperationDescription operationDescription) { }
16: 17: }好,拦截的外壳已经准备好了,来一个实例看看:
1: [ServiceContract(Namespace="urn:Zhenway.Test")]
2: public interface ITest
3: { 4: [Controller] 5: [OperationContract] 6: TestResponse Test(TestRequest req); 7: }是不是很简单。
下篇预告
今天说了半天,都在说如何拦截的问题,还有个更大的问题如何路由,以及怎么实现动态路由,请看下篇。
浙公网安备 33010602011771号