Mercurial > pub > bltoolkit
comparison Source/Aspects/CounterAspect.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f990fcb411a9 |
---|---|
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 } |