Business Logic Toolkit for .NET
www.bltoolkit.net
|  Home   |  Download   |  Documentation   |  Discussions   |  License   |

  Source.Aspects.CounterAspect.cs

 
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));
        }

        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
    }
}
 
© 2010 www.bltoolkit.net
support@bltoolkit.net