AspectCore是适用于Asp.Net Core 平台的轻量级Aop(Aspect-oriented programming)解决方案,它更好的遵循Asp.Net Core的模块化开发理念,使用AspectCore可以更容易构建低耦合、易扩展的Web应用程序。

在使用过程中,由于相关文档、博客还未更新到.Net Core 3.0,本文操作参考了使用.Net Core 3.0的EasyCaching,并对其中公用的方法进行封装简化。

安装Aspectcore

此处配合微软自家的DI实现,安装Nuget包AspectCore.Extensions.DependencyInjection,其中包含AspectCore.Core和Microsoft.Extensions.DependencyInjection两个依赖。

Install-Package AspectCore.Extensions.DependencyInjection -Version 1.3.0

拦截器

  • 特性拦截器

    新建一个特性拦截器TestInterceptorAttribute,继承AbstractInterceptorAttribute,并重写Invoke方法,在方法中实现拦截相关业务。
public class TestInterceptorAttribute : AbstractInterceptorAttribute
{
public override Task Invoke(AspectContext context, AspectDelegate next)
{
return context.Invoke(next);
}
}
  • 全局拦截器

    新建一个全局拦截器TestInterceptor,继承AbstractInterceptor,并重写Invoke方法,在方法中实现拦截相关业务。
public class TestInterceptor : AbstractInterceptor
{
public override Task Invoke(AspectContext context, AspectDelegate next)
{
return context.Invoke(next);
}
}

注册服务

以下注册方式仅适用于asp.net core 3.0(目前只到3.0),已知在2.2版本中,需要在ConfigureServices方法中返回IServiceProvider,并且program.cs中也不再需要替换ServiceProviderFactory。

1.创建AspectCoreEctensions.cs扩展IServiceCollection

public static class AspectCoreExtensions
{
public static void ConfigAspectCore(this IServiceCollection services)
{
services.ConfigureDynamicProxy(config =>
{
//TestInterceptor拦截器类
//拦截代理所有Service结尾的类
config.Interceptors.AddTyped<TestInterceptor>(Predicates.ForService("*Service"));
});
services.BuildAspectInjectorProvider();
}
}

2.在Startup.cs中注册服务

public void ConfigureServices(IServiceCollection services)
{
services.ConfigAspectCore();
}

3.在Program.cs中替换ServiceProviderFactory

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}).UseServiceProviderFactory(new AspectCoreServiceProviderFactory());

被拦截方法编写

  • 代理接口:在接口上标注Attribute
public interface ITestService
{
[TestInterceptor]
void Test();
}
  • 代理类(方法):在方法上标注Attribute,并且标注virtual
public class TestService
{
[TestInterceptor]
public virtual void Test()
{
//业务代码
}
}

拦截器业务编写

  • 执行被拦截方法
private async Task<object> RunAndGetReturn()
{
await Context.Invoke(Next);
return Context.IsAsync()
? await Context.UnwrapAsyncReturnValue()
: Context.ReturnValue;
}
  • 拦截器中的依赖注入
[FromContainer]
private RedisClient RedisClient { get; set; }
  • 获取被拦截方法的Attribute
private static readonly ConcurrentDictionary<MethodInfo, object[]>
MethodAttributes = new ConcurrentDictionary<MethodInfo, object[]>(); public static T GetAttribute<T>(this AspectContext context) where T : Attribute
{
MethodInfo method = context.ServiceMethod;
var attributes = MethodAttributes.GetOrAdd(method, method.GetCustomAttributes(true));
var attribute = attributes.FirstOrDefault(x => typeof(T).IsAssignableFrom(x.GetType()));
if (attribute is T)
{
return (T)attribute;
}
return null;
}
  • 获取被拦截方法返回值类型
public static Type GetReturnType(this AspectContext context)
{
return context.IsAsync()
? context.ServiceMethod.ReturnType.GetGenericArguments()First()
: context.ServiceMethod.ReturnType;
}
  • 处理拦截器返回结果
private static readonly ConcurrentDictionary<Type, MethodInfo>
TypeofTaskResultMethod = new ConcurrentDictionary<Type, MethodInfo>();
public object ResultFactory(this AspectContext context,object result)
{
var returnType = context.GetReturnType(); //异步方法返回Task<T>类型结果
if (context.IsAsync())
{
return TypeofTaskResultMethod
.GetOrAdd(returnType, t => typeof(Task)
.GetMethods()
.First(p => p.Name == "FromResult" && p.ContainsGenericParameters)
.MakeGenericMethod(returnType))
.Invoke(null, new object[] { result });
}
else
{
return result;
}
}

相关链接

ASP.NET Core 3.0 使用AspectCore-Framework实现AOP的更多相关文章

  1. ASP.NET Core 1.0: Using Entity Framework Core

    伴随着ASP.NET Core 1.0发布的还有Entity Framework Core 1.0; 官方文档链接:https://docs.efproject.net/en/latest/platf ...

  2. 打造静态分析器(二)基于Asp.Net Core 3.0的AspectCore组件检测

    上一篇,我们打造了一个简单的分析器,但是我们实际使用分析器就是为了对项目做分析检测,增加一些非语法的自检的 比如Asp.Net Core 3.0的替换依赖注入检测 设计分析 我们创建一个默认的Asp. ...

  3. [转]ASP.NET Core 1.0: Using Entity Framework Core 1.0 - Transaction

    本文转自:http://blog.csdn.net/alvachien/article/details/51576961 跟Entity Framework之前的版本不同,Class DbContex ...

  4. ASP.NET Core 1.0: Using Entity Framework Core 1.0 - Transaction

    跟Entity Framework之前的版本不同,Class DbContext不再有AcceptAllChanges()方法. 使用Transaction需要使用DbContext中的Databas ...

  5. ASP.NET Core 1.0、ASP.NET MVC Core 1.0和Entity Framework Core 1.0

    ASP.NET 5.0 将改名为 ASP.NET Core 1.0 ASP.NET MVC 6  将改名为 ASP.NET MVC Core 1.0 Entity Framework 7.0    将 ...

  6. [转帖]2016年时的新闻:ASP.NET Core 1.0、ASP.NET MVC Core 1.0和Entity Framework Core 1.0

    ASP.NET Core 1.0.ASP.NET MVC Core 1.0和Entity Framework Core 1.0 http://www.cnblogs.com/webapi/p/5673 ...

  7. .NET Core & ASP.NET Core 1.0在Redhat峰会上正式发布

    众所周知,Red Hat和微软正在努力使.NET Core成为Red Hat企业版Linux (RHEL)系统上的一流开发平台选项.这个团队已经一起工作好几个月了,RHEL对.NET有许多需求.今天在 ...

  8. .NET Core & ASP.NET Core 1.0

    .NET Core & ASP.NET Core 1.0在Redhat峰会上正式发布 众所周知,Red Hat和微软正在努力使.NET Core成为Red Hat企业版Linux (RHEL) ...

  9. .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0简介

    .NET Core 1.0.ASP.NET Core 1.0和EF Core 1.0简介 英文原文:Reintroducing .NET Core 1.0, ASP.NET Core 1.0, and ...

  10. [争什么! 掺在一起做撒尿牛丸啊! 笨蛋]ASP.NET Core 2.0 + EF6 + Linux +MySql混搭

    好消息!特好消息!同时使用ASP.NET Core 2.0和.NET Framework类库还能运行在linux上的方法来啦! 是的,你没有看错!ASP.NET Core 2.0,.NET Frame ...

随机推荐

  1. python基础(24):面向对象三大特性一(继承)

    1. 继承 1.1 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继 ...

  2. html5+css+js简单了解

    最近敲了敲HTML5的代码,感觉真的是很吸引人的东西,反正我是非常喜欢的,所以想写一点关于HTML的东xi首先呢我了解的不多,所以也是想写一点点我对它的认识.说起HTML5是打开Pycharm敲pyt ...

  3. JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?

    <JavaScript 深入浅出>系列: JavaScript 深入浅出第 1 课:箭头函数中的 this 究竟是什么鬼? JavaScript 深入浅出第 2 课:函数是一等公民是什么意 ...

  4. mysql设置用户密码规则

    一.查看密码规则 SHOW VARIABLES LIKE 'validate_password%'; 二.规则显示介绍 | Variable_name | Value | +------------- ...

  5. Mysql—索引原理与详解

    索引的原理 索引的优点和缺点和使用原则 索引优点: 可以加快数据的检索速度,提高查询速度. 所有的MySql列类型(字段类型)都可以被索引,也就是可以给任意字段建立索引. 全文检索字段进行搜索优化. ...

  6. 深度自编码器(Deep Autoencoder)MATLAB解读

    深度自编码器(Deep Autoencoder)MATLAB解读 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 这篇文章主要讲解Hinton在2006 ...

  7. Tomcat 学习总结(1) --Servlet技术

    在Web应用中,Servlet是一门重要的技术,Servlet是利用Java类编写的服务端程序,与平台架构,协议无关. JSP的实质就是Servlet,因为所有的JSP页面传回服务端时要转为Servl ...

  8. G1 垃圾收集器架构和如何做到可预测的停顿(阿里)

    CMS垃圾回收机制 参考:图解 CMS 垃圾回收机制原理,-阿里面试题 CMS与G1的区别 参考:CMS收集器和G1收集器优缺点 写这篇文章是基于阿里面试官的一个问题:众所周期,G1跟其他的垃圾回收算 ...

  9. 【BZOJ2437】[Noi2011]兔兔与蛋蛋(博弈+二分图)

    传送门 题意: 给出一个\(n*m\)的棋盘,上面有若干个黑色棋子,若干个白色棋子,还有一个空格. 每次先手选择一个空格,将它与相邻的某个白色棋子交换:后手则选择一个空格,与相邻的某个黑色棋子交换. ...

  10. C++ class内的 < 和 > 重载,大于号,小于号,重载示例。

    #include <iostream> // overloading "operator = " outside class // < 和 > 是二元操作符 ...