WCF后续之旅(8):通过WCF Extension 实现与MS Enterprise Library Pol
在上一篇文章中,我们通过自定义InstanceProvider实现了WCF和微软Enterprise Library Unity Application Block的集成, 今天我们已相同的方式实现WCF与Enterprise Library的另一个Application Block的集成:Policy Injection Application Block (PIAB)。
PIAB,通过Method Interception的机制实现了AOP(Aspect Oriented Programing)。按照PIAB的编程方式,我们将非业务逻辑,比如Caching、Authorization、Transaction Enlist、Auditing、ExceptionHandling扽等等, 定义在一个个的CallHandler,这些CallHandler通过Attribute或者Configuration的方式应用到目标方法上。关于PIAB的详细介绍,我们参考我的PIAB系列
由于PIAB特殊的实现机制,我们需要通过PIAB的PolicyInjector来创建新的对象或者包装现有的目标对象。只有调用这种能够方式的对象,应用在上面的CallHandler才能被执行。所以WCF和PIAB的核心问题就是如何通过PIAB PolicyInjector来创建新的Service Instance,或者包装已经生成的service instance。在上面一篇文章中,我们通过Unity Container重新定义了InstanceProvider,我们今天的实现方案也是通过自定义InstanceProvider的方式来实现,不是我们需需要通过PolicyInjector来进行对象的创建。
一、创建基于PolicyInjection的InstanceProvider
下面是我们新的InstanceProvider(PolicyInjectionInstanceProvider )的定义
1: namespace Artech.WCFExtensions
2: {
3: public class PolicyInjectionInstanceProvider : IInstanceProvider
4: {
5: private Type _serviceContractType;
6: private string _policyInjectorName;
7:
8: public PolicyInjectionInstanceProvider(Type serviceContractType, string policyInjectorName)
9: {
10: this._serviceContractType = serviceContractType;
11: this._policyInjectorName = policyInjectorName;
12: }
13: public object GetInstance(InstanceContext instanceContext, Message message)
14: {
15: PolicyInjector policyInjector = null;
16: if (string.IsNullOrEmpty(this._policyInjectorName))
17: {
18: policyInjector = new PolicyInjectorFactory().Create();
19: }
20: else
21: {
22: policyInjector = new PolicyInjectorFactory().Create(this._policyInjectorName);
23: }
24:
25: Type serviceType = instanceContext.Host.Description.ServiceType;
26: object serviceInstance = Activator.CreateInstance(serviceType);
27: if (!this._serviceContractType.IsInte易做图ce && !serviceType.IsMarshalByRef && policyInjector is RemotingPolicyInjector)
28: {
29: return serviceInstance;
30: }
31:
32: return policyInjector.Wrap(serviceInstance, this._serviceContractType);
33: }
34:
35: public object GetInstance(InstanceContext instanceContext)
36: {
37: return this.GetInstance(instanceContext, null);
38: }
39:
40: public void ReleaseInstance(InstanceContext instanceContext, object instance)
41: {
42: IDisposable disposable = instance as IDisposable;
43: if (disposable != null)
44: {
45: disposable.Dispose();
46: }
47: }
48: }
49: }
我们对PolicyInjectionInstanceProvider 的实现进行简单的说明:在PIAB中真正用于创建对象的是PolicyInjector,虽然PIAB中仅仅定义了一种基于Remoting的RemotingPolicyInjector,但是我们可以根据我们的需要实现一些不同Injection方式,比如IL Injection。所以我们定义了一个字段_policyInjectorName在配置中定位我们需要的PolicyInjector。该字段如果为null或者empty,将使用默认的PolicyInjector。PolicyInjection的获取通过下面的代码实现:
1: PolicyInjector policyInjector = null;
2: if (string.IsNullOrEmpty(this._policyInjectorName))
3: {
4: policyInjector = new PolicyInjectorFactory().Create();
5: }
6: else
7: {
8: policyInjector = new PolicyInjectorFactory().Create(this._policyInjectorName);
9: }
能够被RemotingPolicyInjector创建的对象不是满足下面两个条件中的一个:
Target type实现一个Inte易做图ce。
Target Type直接或者间接集成System.MarshalByRefObject.
所以如果不能满足这个条件,我们直接通过反射创建service instance:
1: Type serviceType = instanceContext.Host.Description.ServiceType;
2: object serviceInstance = Activator.CreateInstance(serviceType);
3: if (!this._serviceContractType.IsInte易做图ce && !serviceType.IsMarshalByRef && policyInjector is RemotingPolicyInjector)
4: {
5: return serviceInstance;
6: }
最后我们通过policyInjector 的Wrap方法对service instance进行封装并返回:
1: return policyInjector.Wrap(serviceInstance, this._servi
补充:综合编程 , 其他综合 ,