2020年12月18日星期五

WCF 动态代理与拦截器

使用Castle.Core.dll实现,核心代码是使用Castle.DynamicProxy.ProxyGenerator类的CreateInterfaceProxyWithoutTarget方法动态创建代理对象

NuGet上面Castle.Core的下载量1.78亿之多

1.WCF服务端通过动态代理,在拦截器中校验Ticket、处理异常

服务端动态代理工厂类ProxyFactory代码:

using Castle.DynamicProxy;using SunCreate.Common.Base;using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq;using System.ServiceModel;using System.Text;using System.Threading.Tasks;namespace SunCreate.InfoPlatform.Server.Service{ /// <summary> /// 动态代理工厂 /// </summary> public class ProxyFactory {  /// <summary>  /// 拦截器缓存  /// </summary>  private static ConcurrentDictionary<Type, IInterceptor> _interceptors = new ConcurrentDictionary<Type, IInterceptor>();  /// <summary>  /// 代理对象缓存  /// </summary>  private static ConcurrentDictionary<Type, object> _objs = new ConcurrentDictionary<Type, object>();  private static ProxyGenerator _proxyGenerator = new ProxyGenerator();  /// <summary>  /// 动态创建代理  /// </summary>  /// <typeparam name="T">接口</typeparam>  public static T CreateProxy<T>()  {   Type interfaceType = typeof(T);   IInterceptor interceptor = _interceptors.GetOrAdd(interfaceType, type =>   {    string serviceName = interfaceType.Name.Substring(1); //服务名称    T _impl = HI.Get<T>();    return new ProxyInterceptor<T>(_impl);   });   return (T)_objs.GetOrAdd(interfaceType, type => _proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof(T), interceptor)); //根据接口类型动态创建代理对象,接口没有实现类  } }}

View Code

服务端拦截器类ProxyInterceptor<T>代码:

using Castle.DynamicProxy;using log4net;using SunCreate.Common.Base;using SunCreate.InfoPlatform.Server.Bussiness;using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.ServiceModel;using System.ServiceModel.Channels;using System.Text;using System.Threading.Tasks;namespace SunCreate.InfoPlatform.Server.Service{ /// <summary> /// 拦截器 /// </summary> /// <typeparam name="T">接口</typeparam> public class ProxyInterceptor<T> : IInterceptor {  private static ILog _log = LogManager.GetLogger(typeof(ProxyInterceptor<T>));  private T _impl;  public ProxyInterceptor(T impl)  {   _impl = impl;  }  /// <summary>  /// 拦截方法  /// </summary>  public void Intercept(IInvocation invocation)  {   //准备参数   ParameterInfo[] parameterInfoArr = invocation.Method.GetParameters();   object[] valArr = new object[parameterInfoArr.Length];   for (int i = 0; i < parameterInfoArr.Length; i++)   {    valArr[i] = invocation.GetArgumentValue(i);   }   //执行方法   try   {    if (HI.Get<ISecurityImp>().CheckTicket())    {     invocation.ReturnValue = invocation.Method.Invoke(_impl, valArr);    }   }   catch (Exception ex)   {    _log.Error("ProxyInterceptor " + typeof(T).Name + " " + invocation.Method.Name + " 异常", ex);   }   //out和ref参数处理   for (int i = 0; i < parameterInfoArr.Length; i++)   {    ParameterInfo paramInfo = parameterInfoArr[i];    if (paramInfo.IsOut || paramInfo.ParameterType.IsByRef)    {     invocation.SetArgumentValue(i, valArr[i]);    }   }  } }}

View Code

如何使用:

public List<EscortTask> GetEscortTaskList(){ var impl = ProxyFactory.CreateProxy<SunCreate.InfoPlatform.Server.Bussiness.IBussDataImp>(); return impl.GetEscortTaskList();}

View Code

这里不用再写try catch

2.WCF客户端通过动态代理,在拦截器中添加Ticket、处理异常、Close对象

客户端动态代理工厂类ProxyFactory代码:

using Castle.DynamicProxy;using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq;using System.ServiceModel;using System.Text;using System.Threading.Tasks;namespace SunCreate.InfoPlatform.Client.Bussiness.Imp{ /// <summary> /// 动态代理工厂 /// </summary> public class ProxyFactory {  /// <summary>  /// 拦截器缓存  /// </summary>  private static ConcurrentDictionary<Type, IInterceptor> _interceptors = new ConcurrentDictionary<Type, IInterceptor>();  /// <summary>  /// 代理对象缓存  /// </summary>  private static ConcurrentDictionary<Type, object> _objs = new ConcurrentDictionary<Type, object>();  private static ProxyGenerator _proxyGenerator = new ProxyGenerator();  /// <summary>  /// 动态创建代理  /// </summary>  /// <typeparam name="T">接口</typeparam>  public static T CreateProxy<T>()  {   Type interfaceType = typeof(T);   IInterceptor interceptor = _interceptors.GetOrAdd(interfaceType, type =>   {    string serviceName = interfaceType.Name.Substring(1); //服务名称    ChannelFactory<T> channelFactory = new ChannelFactory<T>(serviceName);    return new ProxyInterceptor<T>(channelFactory);   });   return (T)_objs.GetOrAdd(interfaceType, type => _proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof(T), interceptor)); //根据接口类型动态创建代理对象,接口没有实现类  } }}

View Code

客户端拦截器类ProxyInterceptor<T>代码:

using Castle.DynamicProxy;using log4net;using SunCreate.Common.Base;using SunCreate.InfoPlatform.Client.Bussiness;using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.ServiceModel;using System.ServiceModel.Channels;using System.Text;using System.Threading.Tasks;namespace SunCreate.InfoPlatform.Client.Bussiness.Imp{ /// <summary> /// 拦截器 /// </summary> /// <typeparam name="T">接口</typeparam> public class ProxyInterceptor<T> : IInterceptor {  private static ILog _log = LogManager.GetLogger(typeof(ProxyInterceptor<T>));  private ChannelFactory<T> _channelFactory;  public ProxyInterceptor(ChannelFactory<T> channelFactory)  {   _channelFactory = channelFactory;  }  /// <summary>  /// 拦截方法  /// </summary>  public void Intercept(IInvocation invocation)  {   //准备参数   ParameterInfo[] parameterInfoArr = invocation.Method.GetParameters();   object[] valArr = new object[parameterInfoArr.Length];   for (int i = 0; i < parameterInfoArr.Length; i++)   {    valArr[i] = invocation.GetArgumentValue(i);   }   //执行方法   T server = _channelFactory.CreateChannel();   using (OperationContextScope scope = new OperationContextScope(server as IContextChannel))   {    try    {     HI.Get<ISecurityBussiness>().AddTicket();     invocation.ReturnValue = invocation.Method.Invoke(server, valArr);     var value = HI.Get<ISecurityBussiness>().GetValue();     ((IChannel)server).Close();    }    catch (Exception ex)    {     _log.Error("ProxyInterceptor " + typeof(T).Name + " " + invocation.Method.Name + " 异常", ex);     ((IChannel)server).Abort();    }   }   //out和ref参数处理   for (int i = 0; i < parameterInfoArr.Length; i++)   {    ParameterInfo paramInfo = parameterInfoArr[i];    if (paramInfo.IsOut || paramInfo.ParameterType.IsByRef)    {     invocation.SetArgumentValue(i, valArr[i]);    }   }  } }}

View Code

如何使用:

public List<EscortTask> GetEscortTaskList(){ var service = ProxyFactory.CreateProxy<SunCreate.InfoPlatform.Contract.IBussDataService>(); return service.GetEscortTaskList();}

View Code

这里不用再写try catch

 









原文转载:http://www.shaoqun.com/a/501320.html

环球华网:https://www.ikjzd.com/w/1063

易佰:https://www.ikjzd.com/w/1482

xinong:https://www.ikjzd.com/w/1368


使用Castle.Core.dll实现,核心代码是使用Castle.DynamicProxy.ProxyGenerator类的CreateInterfaceProxyWithoutTarget方法动态创建代理对象NuGet上面Castle.Core的下载量1.78亿之多1.WCF服务端通过动态代理,在拦截器中校验Ticket、处理异常服务端动态代理工厂类ProxyFactory代码:usingCa
feedback:feedback
eprice:eprice
美食悠闲,珠海忘返 - :美食悠闲,珠海忘返 -
重磅 !美国宣布单方面取消中国"发展中国家"待遇:重磅 !美国宣布单方面取消中国"发展中国家"待遇
苏州乐园门票价格_苏州乐园门票多少钱 :苏州乐园门票价格_苏州乐园门票多少钱

没有评论:

发表评论