# 面向切面编程

AOP为Aspect Oriented Programming的缩写,“切面”指的是那些在你写的代码中在项目的不同部分且有相同共性的东西。它可能是你代码中处理异常、记录方法调用、时间处理、重新执行一些方法等等的一些特殊方式

  • 继承接口IInterceptor
  • 实例化接口IINterceptor的唯一方法Intercept
  • void Proceed();表示执行当前的方法和object ReturnValue { get; set; }执行后调用,object[] Arguments参数对象
/// <summary>
/// 实例化IInterceptor唯一方法 
/// </summary>
/// <param name="invocation">包含被拦截方法的信息</param>
public void Intercept(IInvocation invocation)
{
    //记录被拦截方法信息的日志信息
    var dataIntercept = "" +
        $"【当前执行方法】:{ invocation.Method.Name} \r\n" +
        $"【携带的参数有】: {string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())} \r\n";

    try
    {
        MiniProfiler.Current.Step($"执行Service方法:{invocation.Method.Name}() -> ");
        //在被拦截的方法执行完毕后 继续执行当前方法,注意是被拦截的是异步的
        invocation.Proceed();


        // 异步获取异常,先执行
        if (IsAsyncMethod(invocation.Method))
        {

            //Wait task execution and modify return value
            if (invocation.Method.ReturnType == typeof(Task))
            {
                invocation.ReturnValue = InternalAsyncHelper.AwaitTaskWithPostActionAndFinally(
                    (Task)invocation.ReturnValue,
                    async () => await TestActionAsync(invocation),
                    ex =>
                    {
                        LogEx(ex, ref dataIntercept);
                    });
            }
            else //Task<TResult>
            {
                invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPostActionAndFinallyAndGetResult(
                 invocation.Method.ReturnType.GenericTypeArguments[0],
                 invocation.ReturnValue,
                 async () => await TestActionAsync(invocation),
                 ex =>
                 {
                     LogEx(ex, ref dataIntercept);
                 });

            }

        }
        else
        {// 同步1


        }
    }
    catch (Exception ex)// 同步2
    {
        LogEx(ex, ref dataIntercept);

    }

    dataIntercept += ($"【执行完成结果】:{invocation.ReturnValue}");

    Parallel.For(0, 1, e =>
    {
        LogLock.OutSql2Log("AOPLog", new string[] { dataIntercept });
    });

    _hubContext.Clients.All.SendAsync("ReceiveUpdate", LogLock.GetLogData()).Wait();


}

//添加到Autofac容器中,实现注入
builder.RegisterType<BlogLogAOP>();//可以直接替换其他拦截器!一定要把拦截器进行注册

var assemblysServices = Assembly.Load("Blog.Core.Services");

//builder.RegisterAssemblyTypes(assemblysServices).AsImplementedInterfaces();//指定已扫描程序集中的类型注册为提供所有其实现的接口。

builder.RegisterAssemblyTypes(assemblysServices)
		  .AsImplementedInterfaces()
		  .InstancePerLifetimeScope()
		  .EnableInterfaceInterceptors()//引用Autofac.Extras.DynamicProxy;
		  .InterceptedBy(typeof(BlogLogAOP));//可以直接替换拦截器