AOP-拦截器(Interceptor)AutoFac 实现
首先引入Nuget Autofac.Extras.DynamicProxy
手动注入的话想要使用AOP 拦截器就在最后加入
–EnableInterfaceInterceptors 接口拦截添加
–EnableClassInterceptors 类拦截添加
builder.RegisterType<Factory>().Named<IServiceFactory>(typeof(Factory).Name).InstancePerLifetimeScope().EnableInterfaceInterceptors();
builder.RegisterType<FactoryTwo>().Named<IServiceFactory>(typeof(FactoryTwo).Name).InstancePerLifetimeScope().EnableClassInterceptors();
添加拦截器
public class BlogAopLog : IInterceptor
{
/// <summary>
/// 实例化IInterceptor唯一方法
/// </summary>
/// <param name="invocation">包含被拦截方法的信息</param>
public void Intercept(IInvocation invocation)
{
Console.WriteLine("你正在调用方法 \"{0}\" 参数是 {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
invocation.Proceed();
Console.WriteLine("方法执行完毕,返回结果:{0}", invocation.ReturnValue);
}
}
我定义的是在接口使用 在接口上声明 ,我这里声明了一个总接口,用于自动注入(可以参考之前AutoFac自动注入部分),现在添加一项 继承了这个总接口的类可以进入 拦截器
[Intercept(typeof(BlogAopLog))]
public interface IService
{
}
public interface IServiceFactory: IService
{
//这样只要使用Get Post 就会拦截
public Task<int> Get();
public Task<int> Post();
}
但是灵活性太差只能接口类使用,如果只想用于某个方法或者不想用某个方法就可以 就可以使用打标签的方式进行判断 如这样
接口里面打上标签 指示Get方法不被切入
//定义一个空标签指示拥有这个标签的方法不被 切入
public class NoNeedAop:Attribute
{
}
//接口里面打上标签 指示Get方法不被切入
public interface IServiceFactory: IService
{
//[TypeFilter(typeof(NoNeedAop))]
[NoNeedAop]
public Task<int> Get();
public Task<int> Post();
}
//修改拦截器判断是否存在标签
public class BlogAopLog : IInterceptor
{
/// <summary>
/// 实例化IInterceptor唯一方法
/// </summary>
/// <param name="invocation">包含被拦截方法的信息</param>
public void Intercept(IInvocation invocation)
{
//存在这个标签就不拦截这个方法直接通过
//[TypeFilter(typeof(NoNeedAop))] 这种打标签的方法能拿到注入 但是判读取值比较麻烦
var IsHasAttrbute = invocation.Method.CustomAttributes.Any(a => a.ConstructorArguments.Any(x => (string)(((dynamic)x.Value).Name) == typeof(NoNeedAop).Name));
//[NoNeedAop] 这种打标签的方法 用下面这种取值方式
//var IsHasAttrbute = invocation.Method.CustomAttributes.Any(a => a.AttributeType.Name == typeof(NoNeedAop).Name);
if (!IsHasAttrbute)
{
Console.WriteLine("你正在调用方法 \"{0}\" 参数是 {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
invocation.Proceed();
Console.WriteLine("方法执行完毕,返回结果:{0}", invocation.ReturnValue);
}
else
{
invocation.Proceed();
}
}
}
这样的灵活性就提高了一截