# 面向切面编程
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));//可以直接替换拦截器
← Autofac