Autofac之AOP实现执行方法监控

Z技术 2021年02月02日 666次浏览
  1. 安装Autofac.Extras.DynamicProxy,准备AutofacAOP类
public class AutofacAOP : IInterceptor
    {
        public  void Intercept(IInvocation invocation)
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var dataIntercept = "" +
               $"【当前执行方法】:{ invocation.Method.Name} \r\n" +
               $"【执行开始时间】:{ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} \r\n" +
               $"【携带的参数有】: {JsonConvert.SerializeObject(invocation.Arguments)}\r\n";

            try
            {
                //执行当前方法   
                invocation.Proceed();

                var returnType = invocation.Method.ReturnType;
                //异步方法
                if (IsAsyncMethod(invocation.Method))
                {

                    if (returnType != null && returnType == typeof(Task))
                    {
                        //等待方法返回的Task
                        Func<Task> res = async () => await (Task)invocation.ReturnValue;

                        invocation.ReturnValue = res();
                    }
                    else //Task<TResult>
                    {
                        var returnType2 = invocation.Method.ReflectedType;//获取返回类型

                        if (returnType2 != null)
                        {
                            var resultType = invocation.Method.ReturnType.GetGenericArguments()[0];

                            MethodInfo methodInfo = typeof(AutofacAOP).GetMethod("HandleAsync", BindingFlags.Instance | BindingFlags.Public);

                            var mi = methodInfo.MakeGenericMethod(resultType);
                            invocation.ReturnValue = mi.Invoke(this, new[] { invocation.ReturnValue });
                        }
                    }

                    var type = invocation.Method.ReturnType;
                    var resultProperty = type.GetProperty("Result");

                    if (resultProperty != null)
                    {
                        stopwatch.Stop();
                        dataIntercept += $"【执行结束时间】:{ stopwatch.ElapsedMilliseconds} ms\r\n";
                        dataIntercept += ($"【执行完成结果】:{JsonConvert.SerializeObject(resultProperty.GetValue(invocation.ReturnValue))}");
                    }
                }
                //同步方法
                else
                {
                    if (returnType != null && returnType == typeof(void))
                    {

                    }
                    else
                    {
                        stopwatch.Stop();
                        dataIntercept += $"【执行结束时间】:{ stopwatch.ElapsedMilliseconds} ms\r\n";
                        dataIntercept += ($"【执行完成结果】:{JsonConvert.SerializeObject(invocation.ReturnValue)}");
                    }
                }

                Console.WriteLine(dataIntercept);

            }
            catch (Exception ex)
            {
                LogEx(ex, dataIntercept);
            }
        }

        //构造等待返回值的异步方法
        public async Task<T> HandleAsync<T>(Task<T> task)
        {
            var t = await task;

            return t;
        }

        private void LogEx(Exception ex, string dataIntercept)
        {
            if (ex != null)
            {
                //执行的 service 中,捕获异常
                dataIntercept += ($"【执行完成结果】:方法中出现异常:{ex.Message + ex.InnerException}\r\n");

                // 异常日志里有详细的堆栈信息
                Parallel.For(0, 1, e =>
                {
                    Console.WriteLine(dataIntercept);                    
                });
            }
        }

        /// <summary>
        /// 判断是否异步方法
        /// </summary>
        public static bool IsAsyncMethod(MethodInfo method)
        {
            return (
                method.ReturnType == typeof(Task) ||
                (method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
                );
        }
    }

2.注入服务 有两种方式

  • 方式一,开启服务单个监控
     
     builder.RegisterAssemblyTypes(System.Reflection.Assembly.Load(np))
                        .Where(m => baseType.IsAssignableFrom(m) && m != baseType)
                        .AsImplementedInterfaces()
                        .InstancePerDependency()
                        .InstancePerLifetimeScope()
                        .EnableInterfaceInterceptors()//开启拦截器
                        ;
    在指定被注入的服务类上加上
        [Intercept(typeof(AutofacAOP))]
        public class HomesService: IHomesService
        {
    
    }</code></pre>  </li>
    

    更多信息请关注公众号:
    20220401152838