public void OnMethodEnter(MethodExecutionArguments args)
        {
            // Create stopwatch to measure time and start it
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            // Register variable in arguments
            args.AddVariable(NAME_STOPWATCH_VARIABLE, stopwatch);
        }
        public void OnMethodExit(MethodExecutionArguments args)
        {
            // Get Stopwatch variable
            var sw = args.GetVariable <Stopwatch>(NAME_STOPWATCH_VARIABLE);

            sw.Stop();

            // Create list of arguments for method
            var paramList = new StringBuilder();
            var sbGeneric = new StringBuilder();
            var num       = 0;

            // Generate generic string
            foreach (var genericArgument in args.method.GetGenericArguments())
            {
                if (num > 0)
                {
                    sbGeneric.Append(", ");
                }
                sbGeneric.Append(genericArgument);
                num++;
            }

            num = 0;

            // Generate param string
            args.arguments.ForEach(a =>
            {
                if (num > 0)
                {
                    paramList.Append(", ");
                }
                paramList.Append(a.name);
                num++;
            });
            Debug.Log("[MethodTimeLogger] Method '" +
                      args.rootMethod.Name + (!string.IsNullOrEmpty(sbGeneric.ToString()) ? "<" + sbGeneric + ">" : "") + "(" + paramList + ")' took " + sw.ElapsedMilliseconds + "ms.");
        }
Esempio n. 3
0
        public static object OnMethod(object instance, Type type, string methodName, object[] args)
        {
            // Create arguments for aspects
            var arguments = new MethodExecutionArguments();

            // Get types for args
            var typeArray = new List <Type>();

            foreach (var o in args)
            {
                if (o != null)
                {
                    typeArray.Add(o.GetType());
                }
            }


            // Get methods and generate generic versions for invocation
            var genericTypes = null as List <Type>;
            var method       = type?.GetMethod(methodName + APPENDIX, typeArray, out genericTypes);

            if (genericTypes.Count > 0)
            {
                method = method.MakeGenericMethod(genericTypes.ToArray());
            }

            var containingMethod = type?.GetMethod(methodName, typeArray, out genericTypes);

            if (genericTypes.Count > 0)
            {
                containingMethod = containingMethod.MakeGenericMethod(genericTypes.ToArray());
            }

            // Load data
            arguments.method     = method;
            arguments.rootMethod = containingMethod;
            var mParam = method.GetParameters();

            // Generate arguments for execution args
            for (var index = 0; index < args.Length; index++)
            {
                var pValue = args[index];
                var pName  = mParam[index].Name;
                arguments.arguments.Add(new MethodArgument(pName, pValue));
            }

            // Get start aspects and process them
            var startAspects = containingMethod.GetCustomAttributes(typeof(IMethodEnterAspect), true);

            foreach (var aspect in startAspects)
            {
                ((IMethodEnterAspect)aspect).OnMethodEnter(arguments);
            }

            try
            {
                // TODO: generic methods?
                arguments.returnValue = method.Invoke(instance, args);
            }
            catch (Exception ex)
            {
                arguments.exception = ex.InnerException;
            }

            // Get start aspects and process them
            var exitAspects = containingMethod.GetCustomAttributes(typeof(IMethodExitAspect), true);

            foreach (var aspect in exitAspects)
            {
                ((IMethodExitAspect)aspect).OnMethodExit(arguments);
            }

            // If had error throw it again after processing
            if (arguments.HasErrored)
            {
                // Invoke event if exists
                arguments.onException?.Invoke(arguments.exception);

                // Invoke exception aspects
                var exceptionAspects = containingMethod.GetCustomAttributes(typeof(IMethodExceptionThrownAspect), true);
                foreach (var aspect in exceptionAspects)
                {
                    ((IMethodExceptionThrownAspect)aspect).OnExceptionThrown(arguments.exception, arguments);
                }

                // Rethrow exception
                // ReSharper disable once PossibleNullReferenceException, already checked using HasErrored
                throw arguments.exception;
            }


            // Return value
            return(arguments.returnValue);
        }