/// <summary> /// Intercept an asynchronous operation that returns a Task. /// </summary> private static async Task InterceptAsync(Task task, IInvocation invocation, InterceptEvent intEvent, AuditScope scope) { try { await task.ConfigureAwait(false); } catch { EndAsyncAuditInterceptEvent(task, invocation, intEvent, scope, null); throw; } EndAsyncAuditInterceptEvent(task, invocation, intEvent, scope, "Void"); }
/// <summary> /// Creates the audit intercept event. Returns NULL if the event should be bypassed /// </summary> private InterceptEvent CreateAuditInterceptEvent(IInvocation invocation) { var method = invocation.MethodInvocationTarget; if (method == null) { // operation is not implemented return(null); } bool ignore = method.GetCustomAttributes(typeof(AuditIgnoreAttribute), true).FirstOrDefault() != null; if (ignore) { // operation is explicitly ignored return(null); } bool isProp = method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_")); if (isProp && Settings.IgnoreProperties) { // operation is a property getter/setter and should be ignored return(null); } bool isEvent = method.IsSpecialName && (method.Name.StartsWith("add_") || method.Name.StartsWith("remove_")); if (isEvent && Settings.IgnoreEvents) { // operation is an event attach/detach and should be ignored return(null); } if (Settings.MethodFilter != null) { if (!Settings.MethodFilter.Invoke(method)) { // operation was filtered out return(null); } } var intEvent = new InterceptEvent() { ClassName = invocation.TargetType.Name, InstanceQualifiedName = invocation.TargetType.AssemblyQualifiedName, MethodName = method.Name, MethodSignature = method.ToString(), PropertyName = isProp ? method.Name.Substring(method.Name.IndexOf('_') + 1) : null, EventName = isEvent ? method.Name.Substring(method.Name.IndexOf('_') + 1) : null, Arguments = GetInputParams(invocation) }; return(intEvent); }
/// <summary> /// Ends the event successfully. /// </summary> /// <param name="invocation">The invocation.</param> /// <param name="intEvent">The int event.</param> /// <param name="returnValue">The return value.</param> private static void SuccessAuditInterceptEvent(IInvocation invocation, InterceptEvent intEvent, object returnValue) { var method = invocation.MethodInvocationTarget; intEvent.Success = true; if (IncludeReturnValue(method)) { intEvent.Result = new AuditInterceptArgument(method.ReturnType, returnValue); } // update the output param values if (intEvent.Arguments != null) { var methodParams = method.GetParameters(); for (int i = 0; i < intEvent.Arguments.Count; i++) { var arg = intEvent.Arguments[i]; if (methodParams[arg.Index.Value].ParameterType.IsByRef) { arg.OutputValue = invocation.Arguments[arg.Index.Value]; } } } }
/// <summary> /// Ends the event for asynchronous interceptions. /// </summary> private static void EndAsyncAuditInterceptEvent(Task task, IInvocation invocation, InterceptEvent intEvent, AuditScope scope, object result) { intEvent.AsyncStatus = task.Status.ToString(); if (task.Status == TaskStatus.Faulted) { intEvent.Exception = task.Exception?.GetExceptionInfo(); } else if (task.Status == TaskStatus.RanToCompletion) { SuccessAuditInterceptEvent(invocation, intEvent, result); } scope.Save(); }
/// <summary> /// Intercept an asynchronous operation that returns a Task Of[T]. /// </summary> private static async Task <T> InterceptAsync <T>(Task <T> task, IInvocation invocation, InterceptEvent intEvent, AuditScope scope) { T result; try { result = await task.ConfigureAwait(false); } catch { EndAsyncAuditInterceptEvent(task, invocation, intEvent, scope, null); throw; } EndAsyncAuditInterceptEvent(task, invocation, intEvent, scope, result); return(result); }