Mercurial > pub > bltoolkit
diff Source/Aspects/CounterAspect.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/Aspects/CounterAspect.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,118 @@ +using System; +using System.Collections; +using System.Reflection; +using System.Threading; + +namespace BLToolkit.Aspects +{ + public delegate MethodCallCounter CreateCounter(CallMethodInfo methodInfo); + + /// <summary> + /// http://www.bltoolkit.net/Doc/Aspects/index.htm + /// </summary> + [System.Diagnostics.DebuggerStepThrough] + public class CounterAspect : Interceptor + { + public override void Init(CallMethodInfo info, string configString) + { + base.Init(info, configString); + + _counters.Add(_counter = CreateCounter(info) ?? CreateCounterInternal(info)); + } + + private MethodCallCounter _counter; + + static readonly LocalDataStoreSlot _counterSlot = Thread.AllocateDataSlot(); + + protected override void BeforeCall(InterceptCallInfo info) + { + if (!IsEnabled || Thread.GetData(_counterSlot) != null) + return; + + _counter.RegisterCall(info); + + Thread.SetData(_counterSlot, _counter); + } + + protected override void OnFinally(InterceptCallInfo info) + { + if (!IsEnabled) + return; + + MethodCallCounter prev = (MethodCallCounter)Thread.GetData(_counterSlot); + + if (_counter == prev) + { + _counter.UnregisterCall(info); + + Thread.SetData(_counterSlot, null); + } + } + + #region Parameters + + private static bool _isEnabled = true; + public static bool IsEnabled + { + get { return _isEnabled; } + set { _isEnabled = value; } + } + + #endregion + + #region Counter + + private static readonly ArrayList _counters = ArrayList.Synchronized(new ArrayList()); + public static ArrayList Counters + { + get { return _counters; } + } + + public static MethodCallCounter GetCounter(MethodInfo methodInfo) + { + lock (_counters.SyncRoot) + foreach (MethodCallCounter c in _counters) + { + if ((methodInfo.DeclaringType == c.MethodInfo.DeclaringType || + methodInfo.DeclaringType == c.MethodInfo.DeclaringType.BaseType) && + methodInfo.Name == c.MethodInfo.Name) + { + ParameterInfo[] ps1 = c.MethodInfo.GetParameters(); + ParameterInfo[] ps2 = methodInfo.GetParameters(); + + if (ps1.Length == ps2.Length) + { + bool isMatched = true; + + for (int i = 0; isMatched && i < ps1.Length; i++) + isMatched = ps1[i].ParameterType == ps2[i].ParameterType; + + if (isMatched) + return c; + } + } + } + + return null; + } + + #region CreateCounter + + private static CreateCounter _createCounter = CreateCounterInternal; + + public static CreateCounter CreateCounter + { + get { return _createCounter; } + set { _createCounter = value ?? new CreateCounter(CreateCounterInternal); } + } + + private static MethodCallCounter CreateCounterInternal(CallMethodInfo methodInfo) + { + return new MethodCallCounter(methodInfo); + } + + #endregion + + #endregion + } +}