2024年5月10日发(作者:)

WCF服务端基于配置的实现——拦截

如果说到拦截器,相信大家都不陌生,所有的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 teInputs();

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, objec

t 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(, Inherited = false, AllowMultiple = false)]

2: public sealed class ControllerAttribute

3: : Attribute, IOperationBehavior

4: {

5:

6: void dingParameters(OperationDescription operationDescription,

BindingParameterCollection bindingParameters) { }

7:

8: void lientBehavior(OperationDescription operationDescription,

ClientOperation clientOperation) { }

9:

10: void ispatchBehavior(OperationDescription operationDescriptio

n, DispatchOperation dispatchOperation)

11: {

12: r = new ControllerInvoker(r);

13: }

14:

15: void te(OperationDescription operationDescription) { }

16:

17: }

好,拦截的外壳已经准备好了,来一个实例看看:

1: [ServiceContract(Namespace="urn:")]

2: public interface ITest

3: {

4: [Controller]

5: [OperationContract]

6: TestResponse Test(TestRequest req);

7: }

是不是很简单。