C# 实现 Aop [继承ContextBoundObject方式]

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倍.

你可能感兴趣的:(context)