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