0
|
1 using System;
|
|
2 using System.Collections;
|
|
3 using System.Reflection;
|
|
4 using System.Threading;
|
|
5
|
|
6 namespace BLToolkit.Aspects
|
|
7 {
|
|
8 public delegate MethodCallCounter CreateCounter(CallMethodInfo methodInfo);
|
|
9
|
|
10 /// <summary>
|
|
11 /// http://www.bltoolkit.net/Doc/Aspects/index.htm
|
|
12 /// </summary>
|
|
13 [System.Diagnostics.DebuggerStepThrough]
|
|
14 public class CounterAspect : Interceptor
|
|
15 {
|
|
16 public override void Init(CallMethodInfo info, string configString)
|
|
17 {
|
|
18 base.Init(info, configString);
|
|
19
|
|
20 _counters.Add(_counter = CreateCounter(info) ?? CreateCounterInternal(info));
|
|
21 }
|
|
22
|
|
23 private MethodCallCounter _counter;
|
|
24
|
|
25 static readonly LocalDataStoreSlot _counterSlot = Thread.AllocateDataSlot();
|
|
26
|
|
27 protected override void BeforeCall(InterceptCallInfo info)
|
|
28 {
|
|
29 if (!IsEnabled || Thread.GetData(_counterSlot) != null)
|
|
30 return;
|
|
31
|
|
32 _counter.RegisterCall(info);
|
|
33
|
|
34 Thread.SetData(_counterSlot, _counter);
|
|
35 }
|
|
36
|
|
37 protected override void OnFinally(InterceptCallInfo info)
|
|
38 {
|
|
39 if (!IsEnabled)
|
|
40 return;
|
|
41
|
|
42 MethodCallCounter prev = (MethodCallCounter)Thread.GetData(_counterSlot);
|
|
43
|
|
44 if (_counter == prev)
|
|
45 {
|
|
46 _counter.UnregisterCall(info);
|
|
47
|
|
48 Thread.SetData(_counterSlot, null);
|
|
49 }
|
|
50 }
|
|
51
|
|
52 #region Parameters
|
|
53
|
|
54 private static bool _isEnabled = true;
|
|
55 public static bool IsEnabled
|
|
56 {
|
|
57 get { return _isEnabled; }
|
|
58 set { _isEnabled = value; }
|
|
59 }
|
|
60
|
|
61 #endregion
|
|
62
|
|
63 #region Counter
|
|
64
|
|
65 private static readonly ArrayList _counters = ArrayList.Synchronized(new ArrayList());
|
|
66 public static ArrayList Counters
|
|
67 {
|
|
68 get { return _counters; }
|
|
69 }
|
|
70
|
|
71 public static MethodCallCounter GetCounter(MethodInfo methodInfo)
|
|
72 {
|
|
73 lock (_counters.SyncRoot)
|
|
74 foreach (MethodCallCounter c in _counters)
|
|
75 {
|
|
76 if ((methodInfo.DeclaringType == c.MethodInfo.DeclaringType ||
|
|
77 methodInfo.DeclaringType == c.MethodInfo.DeclaringType.BaseType) &&
|
|
78 methodInfo.Name == c.MethodInfo.Name)
|
|
79 {
|
|
80 ParameterInfo[] ps1 = c.MethodInfo.GetParameters();
|
|
81 ParameterInfo[] ps2 = methodInfo.GetParameters();
|
|
82
|
|
83 if (ps1.Length == ps2.Length)
|
|
84 {
|
|
85 bool isMatched = true;
|
|
86
|
|
87 for (int i = 0; isMatched && i < ps1.Length; i++)
|
|
88 isMatched = ps1[i].ParameterType == ps2[i].ParameterType;
|
|
89
|
|
90 if (isMatched)
|
|
91 return c;
|
|
92 }
|
|
93 }
|
|
94 }
|
|
95
|
|
96 return null;
|
|
97 }
|
|
98
|
|
99 #region CreateCounter
|
|
100
|
|
101 private static CreateCounter _createCounter = CreateCounterInternal;
|
|
102
|
|
103 public static CreateCounter CreateCounter
|
|
104 {
|
|
105 get { return _createCounter; }
|
|
106 set { _createCounter = value ?? new CreateCounter(CreateCounterInternal); }
|
|
107 }
|
|
108
|
|
109 private static MethodCallCounter CreateCounterInternal(CallMethodInfo methodInfo)
|
|
110 {
|
|
111 return new MethodCallCounter(methodInfo);
|
|
112 }
|
|
113
|
|
114 #endregion
|
|
115
|
|
116 #endregion
|
|
117 }
|
|
118 }
|