现在通用的做法一般有两种:一个是上下文消息传递,一个是利用代理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

3



4

5

6

7



8

9

10

11

12



13

14



15

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

4



5

6

7

8



9

10

11

12



13

14

15

16



17

18



19

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

4

5

6

7



8

9

10

11

12

13



14

15



16

17

18

19

20

21



22

23

24

25

26

27

28

29



30

31

32

33

34



35

36



37

38

39

40

41

42

43

44

45

46



47

48



49

50

51

52

53

54

55

56

57



58

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

3



4

5



6

7

8

9

10



11

12

13

14

15



16

17

18

19

20



21

22

23

24

25

26

27

28

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框架。
以上,希望对大家有所帮助。