利用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
}
然后,把写日志这件事情加入到上下文中。
[AttributeUsage(AttributeTargets.Class)]2
public class LogPointer : ContextAttribute3
{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
}
最后,还需要在消息链中处理消息。
public class LogHandler : IContextProperty, IContributeObjectSink2
{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 Name16
{17
get18
{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实现就完成了。
public class LogTrack : IMessageSink2
{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 NextSink13
{14
get15
{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
}
需要注意的是,代码中红色部分是必须的。
[LogPointer("Log")]2
public class Test:ContextBoundObject3
{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框架。
以上,希望对大家有所帮助。

浙公网安备 33010602011771号