利用Attribute实现AOP
AOP现在是如火如荼,DotNet下的AOP框架也不少,但是如果你仅仅是需要写日志、权限管理这样的不是十分庞大规模的模块的话,真的是没有必要去引用一个或多个dll,所谓的“没有你在,我自己来”,也大概就是这样吧。
现在通用的做法一般有两种:一个是上下文消息传递,一个是利用代理RealProxy,这里的做法是前面一种。
首先定义一个Attribute。
我们来测试一下:
到这里,就大功告成了,当然,实际应用中,你可以把这些东西抽象封装一下,让它更具有通用性。
写完了这篇东西,去百度搜索了一下,原来这样子的实现简直太多了,给大家介绍几个:
1)http://www.brucezhang.com/articles/256909.html
这是一个园里的大牛写的,内容很丰富。
2)http://msdn.microsoft.com/msdnmag/issues/02/03/AOP/
这是MSDN2002年的一篇文章。
3)http://www.cs-open.com/sort/1.html
一些开源的AOP框架。
以上,希望对大家有所帮助。
现在通用的做法一般有两种:一个是上下文消息传递,一个是利用代理RealProxy,这里的做法是前面一种。
首先定义一个Attribute。
1 [AttributeUsage(AttributeTargets.Class)]
2 public class LogPointer : ContextAttribute
3 {
4 private String pointName = null;
5
6 public LogPointer(string pName) : base(pName)
7 {
8 this.pointName = pName;
9 }
10
11 public override void GetPropertiesForNewContext(IConstructionCallMessage ccm)
12 {
13 if (pointName == "Log")
14 {
15 ccm.ContextProperties.Add(new LogHandler());
16 }
17 }
18 }
然后,把写日志这件事情加入到上下文中。
2 public class LogPointer : ContextAttribute
3 {
4 private String pointName = null;
5
6 public LogPointer(string pName) : base(pName)
7 {
8 this.pointName = pName;
9 }
10
11 public override void GetPropertiesForNewContext(IConstructionCallMessage ccm)
12 {
13 if (pointName == "Log")
14 {
15 ccm.ContextProperties.Add(new LogHandler());
16 }
17 }
18 }
1 public class LogHandler : IContextProperty, IContributeObjectSink
2 {
3 public IMessageSink GetObjectSink(MarshalByRefObject o, IMessageSink next)
4 {
5 return new LogTrack(o, next);
6 }
7 public bool IsNewContextOK(Context newCtx)
8 {
9 return true;
10 }
11 public void Freeze(Context newContext)
12 {
13 }
14
15 public string Name
16 {
17 get
18 {
19 return "LogHandler";
20 }
21 }
22 }
最后,还需要在消息链中处理消息。
2 {
3 public IMessageSink GetObjectSink(MarshalByRefObject o, IMessageSink next)
4 {
5 return new LogTrack(o, next);
6 }
7 public bool IsNewContextOK(Context newCtx)
8 {
9 return true;
10 }
11 public void Freeze(Context newContext)
12 {
13 }
14
15 public string Name
16 {
17 get
18 {
19 return "LogHandler";
20 }
21 }
22 }
1 public class LogTrack : IMessageSink
2 {
3 private IMessageSink m_imNext;
4 private Object obj;
5
6 public LogTrack(MarshalByRefObject o, IMessageSink next)
7 {
8 obj = o;
9 m_imNext = next;
10 }
11
12 public IMessageSink NextSink
13 {
14 get
15 {
16 return m_imNext;
17 }
18 }
19
20 public IMessage SyncProcessMessage(IMessage msg)
21 {
22 BeforeMethodStart(msg);
23 IMessage returnMethod = m_imNext.SyncProcessMessage(msg);
24 AfterMethodEnd(msg, returnMethod);
25 return returnMethod;
26 }
27
28 public IMessage CtrlAsyncProcessMessage(IMessage msg, IMessageSink replySink)
29 {
30 throw new Exception("noAsyncProcessMessage");
31 }
32
33 private void BeforeMethodStart(IMessage msg)
34 {
35 if (!(msg is IMethodMessage))
36 {
37 return;
38 }
39
40 IMethodMessage ifcMsg = msg as IMethodMessage;
41 System.Console.WriteLine("LogTrack: " + obj.GetType().ToString() + "." + ifcMsg.MethodName + " Started");
42 }
43
44
45 private void AfterMethodEnd(IMessage msg, IMessage msgReturn)
46 {
47 if (!((msg is IMethodMessage) && (msgReturn is IMethodReturnMessage)))
48 {
49 return;
50 }
51
52 IMethodMessage ifcMsg = msg as IMethodMessage;
53 System.Console.WriteLine("LogTrack: " + obj.GetType().ToString() + "." + ifcMsg.MethodName + " Ended");
54 }
55
56 public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
57 {
58 throw new Exception("The method or operation is not implemented.");
59 }
60 }
这样子,一个写日志的AOP实现就完成了。2 {
3 private IMessageSink m_imNext;
4 private Object obj;
5
6 public LogTrack(MarshalByRefObject o, IMessageSink next)
7 {
8 obj = o;
9 m_imNext = next;
10 }
11
12 public IMessageSink NextSink
13 {
14 get
15 {
16 return m_imNext;
17 }
18 }
19
20 public IMessage SyncProcessMessage(IMessage msg)
21 {
22 BeforeMethodStart(msg);
23 IMessage returnMethod = m_imNext.SyncProcessMessage(msg);
24 AfterMethodEnd(msg, returnMethod);
25 return returnMethod;
26 }
27
28 public IMessage CtrlAsyncProcessMessage(IMessage msg, IMessageSink replySink)
29 {
30 throw new Exception("noAsyncProcessMessage");
31 }
32
33 private void BeforeMethodStart(IMessage msg)
34 {
35 if (!(msg is IMethodMessage))
36 {
37 return;
38 }
39
40 IMethodMessage ifcMsg = msg as IMethodMessage;
41 System.Console.WriteLine("LogTrack: " + obj.GetType().ToString() + "." + ifcMsg.MethodName + " Started");
42 }
43
44
45 private void AfterMethodEnd(IMessage msg, IMessage msgReturn)
46 {
47 if (!((msg is IMethodMessage) && (msgReturn is IMethodReturnMessage)))
48 {
49 return;
50 }
51
52 IMethodMessage ifcMsg = msg as IMethodMessage;
53 System.Console.WriteLine("LogTrack: " + obj.GetType().ToString() + "." + ifcMsg.MethodName + " Ended");
54 }
55
56 public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
57 {
58 throw new Exception("The method or operation is not implemented.");
59 }
60 }
我们来测试一下:
1 [LogPointer("Log")]
2 public class Test:ContextBoundObject
3 {
4 public void say(string s, string ss)
5 {
6 System.Console.WriteLine("in say method:say something");
7 }
8
9 public void doTest()
10 {
11 System.Console.WriteLine("in do method:do something");
12 }
13
14 public string returnNone(int x)
15 {
16 System.Console.WriteLine("in returnNone method:" + x.ToString());
17 return "-------" + x;
18 }
19 public static void Main()
20 {
21 Test at = new Test();
22
23 at.say("test say", "say");
24 at.doTest();
25 string str = at.returnNone(99);
26 Console.WriteLine(str);
27
28 Console.ReadKey();
29 }
30 }
需要注意的是,代码中红色部分是必须的。2 public class Test:ContextBoundObject
3 {
4 public void say(string s, string ss)
5 {
6 System.Console.WriteLine("in say method:say something");
7 }
8
9 public void doTest()
10 {
11 System.Console.WriteLine("in do method:do something");
12 }
13
14 public string returnNone(int x)
15 {
16 System.Console.WriteLine("in returnNone method:" + x.ToString());
17 return "-------" + x;
18 }
19 public static void Main()
20 {
21 Test at = new Test();
22
23 at.say("test say", "say");
24 at.doTest();
25 string str = at.returnNone(99);
26 Console.WriteLine(str);
27
28 Console.ReadKey();
29 }
30 }
到这里,就大功告成了,当然,实际应用中,你可以把这些东西抽象封装一下,让它更具有通用性。
写完了这篇东西,去百度搜索了一下,原来这样子的实现简直太多了,给大家介绍几个:
1)http://www.brucezhang.com/articles/256909.html
这是一个园里的大牛写的,内容很丰富。
2)http://msdn.microsoft.com/msdnmag/issues/02/03/AOP/
这是MSDN2002年的一篇文章。
3)http://www.cs-open.com/sort/1.html
一些开源的AOP框架。
以上,希望对大家有所帮助。