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