Net AOP(三)继承ContextBoundObject方式
AopAttribute
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
- 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 }
- 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 }
- 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 }
- 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 }
- 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倍.