.Net AOP(三)继承ContextBoundObject方式

来源:互联网 发布:游戏王 游戏 知乎 编辑:程序博客网 时间:2024/06/06 21:03

.Net AOP(三)继承ContextBoundObject方式

AopAttribute

  1.   [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
  2.  public class AopAttribute : ProxyAttribute  
  3.  3     {  
  4.  4        private IAopProxyBuilder builder=null;  
  5.  5        public AopAttribute(Type builderType)  
  6.  6        {  
  7.  7            this.builder = (IAopProxyBuilder)Activator.CreateInstance(builderType);  
  8.  8        }  
  9.  9   
  10. 10         public override MarshalByRefObject CreateInstance(Type serverType)  
  11. 11         {  
  12. 12             AopProxy realProxy = new AopProxy(serverType);  
  13. 13             return realProxy.GetTransparentProxy() as MarshalByRefObject;  
  14. 14         }  
  15. 15   
  16. 16   
  17. 17     }  
MethodAopAdviceAttribute

  1.  1   [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]  
  2.  2     public class MethodAopAdviceAttribute : Attribute  
  3.  3     {  
  4.  4   
  5.  5         private AdviceType type=AdviceType.None;  
  6.  6         public MethodAopAdviceAttribute(AdviceType advicetype)  
  7.  7         {  
  8.  8             this.type = advicetype;  
  9.  9         }  
  10. 10   
  11. 11         public AdviceType AdviceType  
  12. 12         {  
  13. 13             get  
  14. 14             {  
  15. 15                 return this.type;  
  16. 16             }  
  17. 17         }  
  18. 18     }  
  19. 19   
  20. 20     public enum AdviceType  
  21. 21     {  
  22. 22         None,  
  23. 23         Before,  
  24. 24         After,  
  25. 25         Around  
  26. 26     }  
AopProxy

  1.   1   partial interface IAopAction  
  2.   2     {  
  3.   3         void PreProcess(IMessage requestMsg);  
  4.   4         void PostProcess(IMessage requestMsg, IMessage Respond);  
  5.   5     }  
  6.   6     public class AopProxy : RealProxy, IAopAction  
  7.   7     {  
  8.   8         public AopProxy(Type serverType)  
  9.   9             : base(serverType)  
  10.  10         {  
  11.  11         }  
  12.  12         public virtual void PreProcess(object obj,string method="",int argCount=0,object[] args=null)  
  13.  13         {  
  14.  14             var o=obj as AopClass;  
  15.  15             if (o!=null)  
  16.  16             {  
  17.  17                 o.IsLock=false;  
  18.  18                 o.Name="999999";  
  19.  19             }  
  20.  20         }  
  21.  21   
  22.  22         public virtual void PreProcess(IMessage requestMsg)  
  23.  23         {    
  24.  24             var o=GetUnwrappedServer();  
  25.  25             IMethodCallMessage call = requestMsg as IMethodCallMessage;  
  26.  26             if (call!=null)  
  27.  27             {  
  28.  28                 this.PreProcess(o, call.MethodName, call.InArgCount, call.Args);  
  29.  29             }  
  30.  30             else  
  31.  31             {  
  32.  32                 this.PreProcess(o);  
  33.  33             }  
  34.  34                     
  35.  35         }  
  36.  36   
  37.  37         public virtual void PostProcess(object obj, object returnValue=null,string method=""int argCount=0object[] args=null)  
  38.  38         {  
  39.  39             var o=obj as AopClass;  
  40.  40             if (o!=null)  
  41.  41             {  
  42.  42                 o.IsLock=true;  
  43.  43                 o.Name="10101010";  
  44.  44             }  
  45.  45             
  46.  46   
  47.  47         }  
  48.  48         public virtual void PostProcess(IMessage requestMsg, IMessage Respond)  
  49.  49         {  
  50.  50               var o=GetUnwrappedServer();           
  51.  51                 ReturnMessage mm=Respond as ReturnMessage;  
  52.  52                 var ret=mm.ReturnValue;  
  53.  53                 IMethodCallMessage call = requestMsg as IMethodCallMessage;  
  54.  54                 if (call!=null)  
  55.  55                 {  
  56.  56                     this.PostProcess(o,ret,call.MethodName, call.InArgCount, call.Args);  
  57.  57                 }  
  58.  58                 else  
  59.  59                 {  
  60.  60                     this.PostProcess(o, ret);  
  61.  61                 }  
  62.  62         }  
  63.  63   
  64.  64         //public virtual IMessage Proessed(IMessage msg,MarshalByRefObject target)  
  65.  65         //{  
  66.  66         //    IMethodCallMessage call = (IMethodCallMessage)msg;  
  67.  67         //    IConstructionCallMessage ctor = call as IConstructionCallMessage;  
  68.  68         //    if (ctor != null)  
  69.  69         //    {  
  70.  70         //        //获取最底层的默认真实代理    
  71.  71         //        RealProxy default_proxy = System.Runtime.Remoting.RemotingServices.GetRealProxy(target);  
  72.  72   
  73.  73         //        default_proxy.InitializeServerObject(ctor);  
  74.  74         //        MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy();  
  75.  75         //        //自定义的透明代理 this    
  76.  76   
  77.  77         //        return System.Runtime.Remoting.Services.EnterpriseServicesHelper.CreateConstructionReturnMessage(ctor, tp);  
  78.  78         //    }  
  79.  79   
  80.  80         //    IMethodReturnMessage result_msg =  System.Runtime.Remoting.RemotingServices.ExecuteMessage(target, call);  
  81.  81         //    //将消息转化为堆栈,并执行目标方法,方法完成后,再将堆栈转化为消息    
  82.  82         //    return result_msg;  
  83.  83         //}  
  84.  84   
  85.  85         public virtual IMessage Proessed(IMessage msg)  
  86.  86         {  
  87.  87             IMessage message;  
  88.  88             if (msg is IConstructionCallMessage)  
  89.  89             {  
  90.  90                 message=this.ProcessConstruct(msg);  
  91.  91             }  
  92.  92             else  
  93.  93             {  
  94.  94                 message=this.ProcessInvoke(msg);  
  95.  95             }  
  96.  96             return message;  
  97.  97         }  
  98.  98         public virtual void ChangeReturnValue(IMessage msg,ref object o)  
  99.  99         {  
  100. 100             if (msg is IMethodCallMessage)  
  101. 101             {  
  102. 102                 var m=msg as IMethodCallMessage;  
  103. 103                 string name= m.MethodName;  
  104. 104                 if(name=="Hello")  
  105. 105                   o="Hello,Lucy!";  
  106. 106             }  
  107. 107         }  
  108. 108         public virtual IMessage ProcessInvoke(IMessage msg)  
  109. 109         {  
  110. 110             IMethodCallMessage callMsg = msg as IMethodCallMessage;  
  111. 111             IMessage message;  
  112. 112             try  
  113. 113             {     
  114. 114                 object[] args = callMsg.Args;   //方法参数                   
  115. 115                 object o = callMsg.MethodBase.Invoke(GetUnwrappedServer(), args);  //调用 原型类的 方法         
  116. 116                 ChangeReturnValue(msg,ref o);  
  117. 117                 message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg);   // 返回类型 Message  
  118. 118             }  
  119. 119             catch (Exception e)  
  120. 120             {  
  121. 121                 message = new ReturnMessage(e, callMsg);  
  122. 122             }  
  123. 123   
  124. 124             //Console.WriteLine("Call Method:"+callMsg.MethodName);  
  125. 125             //Console.WriteLine("Return:"+ message.Properties["__Return"].ToString());  
  126. 126             return message;  
  127. 127         }  
  128. 128         public virtual IMessage ProcessConstruct(IMessage msg)  
  129. 129         {  
  130. 130             IConstructionCallMessage constructCallMsg = msg as IConstructionCallMessage;  
  131. 131             //构造函数 初始化  
  132. 132             IConstructionReturnMessage constructionReturnMessage = this.InitializeServerObject((IConstructionCallMessage)msg);  
  133. 133             RealProxy.SetStubData(this, constructionReturnMessage.ReturnValue);  
  134. 134   
  135. 135             //Console.WriteLine("Call constructor:"+constructCallMsg.MethodName);  
  136. 136             //Console.WriteLine("Call constructor arg count:"+constructCallMsg.ArgCount);  
  137. 137   
  138. 138             return constructionReturnMessage;  
  139. 139         }  
  140. 140   
  141. 141         public override IMessage Invoke(IMessage msg)  
  142. 142         {  
  143. 143              
  144. 144              
  145. 145             #region  获取AdviceType  
  146. 146             AdviceType type=AdviceType.None;  
  147. 147             IMethodCallMessage call = (IMethodCallMessage)msg;             
  148. 148             foreach (Attribute attr in call.MethodBase.GetCustomAttributes(false))  
  149. 149             {  
  150. 150                 MethodAopAdviceAttribute mehodAopAttr = attr as MethodAopAdviceAttribute;  
  151. 151                 if (mehodAopAttr != null)  
  152. 152                 {  
  153. 153                     type=mehodAopAttr.AdviceType;  
  154. 154                     break;  
  155. 155                 }  
  156. 156             }  
  157. 157             #endregion  
  158. 158             IMessage message;           
  159. 159               
  160. 160              
  161. 161             if (type==AdviceType.Before || type==AdviceType.Around)  
  162. 162             {  
  163. 163                 this.PreProcess(msg);   
  164. 164                 Console.WriteLine("::Before Or Around");  
  165. 165             }  
  166. 166             message=this.Proessed(msg);  
  167. 167             if (type==AdviceType.After || type==AdviceType.Around)  
  168. 168             {  
  169. 169                 this.PostProcess(msg, message);  
  170. 170                 Console.WriteLine("::After Or Around");  
  171. 171             }  
  172. 172   
  173. 173             return message;  
  174. 174         }  
  175. 175     }  
AopProxyBuilder

  1.  1  public interface IAopProxyBuilder  
  2.  2     {  
  3.  3         AopProxy CreateAopProxyInstance(Type type);  
  4.  4     }  
  5.  5   
  6.  6     public class AopProxyBuilder : IAopProxyBuilder  
  7.  7     {          
  8.  8         public AopProxy CreateAopProxyInstance(Type type)  
  9.  9         {  
  10. 10             return new AopProxy(type);  
  11. 11         }  
  12. 12     }  
AopClass

  1.  1   [AopAttribute(typeof(AopProxyBuilder))]  
  2.  2     public class AopClass : ContextBoundObject  
  3.  3     {  
  4.  4        
  5.  5         public string Name  
  6.  6         {  
  7.  7             get;  
  8.  8             set;  
  9.  9         }  
  10. 10         public bool IsLock=true;  
  11. 11         public AopClass(string name)  
  12. 12         {  
  13. 13             Name=name;  
  14. 14             Console.WriteLine("Aop Class Create Name:"+Name);  
  15. 15         }  
  16. 16   
  17. 17         public AopClass()  
  18. 18         {  
  19. 19             Console.WriteLine("Aop Class Create");  
  20. 20         }  
  21. 21   
  22. 22           
  23. 23   
  24. 24         [MethodAopAdvice(AdviceType.Around)]  
  25. 25         public string Hello()  
  26. 26         {  
  27. 27             Console.WriteLine("hello world:");  
  28. 28             return "hello world:";  
  29. 29         }  
  30. 30   
  31. 31         [MethodAopAdvice(AdviceType.Before)]  
  32. 32         public string Say(string content)  
  33. 33         {    
  34. 34             string c= "IsLock:"+IsLock+"\t "+Name+" :"+content;  
  35. 35             Console.WriteLine(c);  
  36. 36             return c;  
  37. 37         }  
  38. 38         public override string ToString()  
  39. 39         {  
  40. 40             return string.Format("Name:{0},IsLock:{1}"this.Name, this.IsLock);  
  41. 41   
  42. 42         }  
  43. 43     }  
测试代码

  1.  1    static void Test()  
  2.  2         {  
  3.  3             Console.WriteLine();  
  4.  4             AopClass ap=new AopClass("XiaoQiang");           
  5.  5              Console.WriteLine("Show:"+ ap.Hello());  
  6.  6             Console.WriteLine(ap.ToString());  
  7.  7             Console.WriteLine();  
  8.  8   
  9.  9             Console.WriteLine("Show:"+ ap.Say("hello,everybody!"));  
  10. 10             Console.WriteLine(ap.ToString());  
  11. 11             Console.WriteLine(ap.ToString());  
  12. 12         }  

 【继承object 与继承ContextBoundObject 的性能差】

测试数据

  1.  1  public class ClsA  
  2.  2     {  
  3.  3   
  4.  4         public void ToDo()  
  5.  5         {  
  6.  6   
  7.  7         }  
  8.  8   
  9.  9     }  
  10. 10   
  11. 11     public class ClsB : ContextBoundObject  
  12. 12     {  
  13. 13   
  14. 14         public void ToDo()  
  15. 15         {  
  16. 16   
  17. 17         }  
  18. 18   
  19. 19     }  
性能测试

  1.  1  static void Main(string[] args)  
  2.  2         {           
  3.  3             WatchToDo(ToDoA);  
  4.  4             WatchToDo(ToDoB);  
  5.  5             Console.ReadKey();  
  6.  6         }  
  7.  7   
  8.  8        static  void ToDoA()  
  9.  9         {  
  10. 10             ClsA cl1 = new ClsA();  
  11. 11             cl1.ToDo();  
  12. 12         }  
  13. 13        static void ToDoB()  
  14. 14         {  
  15. 15             ClsB cl2 = new ClsB();  
  16. 16             cl2.ToDo();  
  17. 17         }  
  18. 18         static long WatchToDo(Action act)  
  19. 19         {  
  20. 20             System.Diagnostics.Stopwatch stop = new System.Diagnostics.Stopwatch();  
  21. 21             stop.Reset();  
  22. 22             stop.Start();  
  23. 23             for (int i=0; i<10000; i++)  
  24. 24                 act();  
  25. 25             stop.Stop();  
  26. 26             Console.WriteLine("Time: "+stop.ElapsedTicks);  
  27. 27             return stop.ElapsedTicks;  
  28. 28         }  

 测试结果:性能时间后者是前者的392倍.


0 0
原创粉丝点击