dotnetcore实现Aop
dotnetcore实现aop
aop大家都不陌生,然而今天给大家不将讲官方的filter,今天给大家分享一个轻量级的aop解决方案(aspectcore)
什么是aspectcore
aspectcore是一个面向切面编程,基于.netcore和.netframwork的扩平台框架,对方法拦截器、依赖项注入集成、web应用程序、数据验证等提供核心支持。
aspectcore基本特性
-
提供抽象的aop接口,基于该接口可以轻松的使用自己的代理类实现替换默认的实现.
-
框架不包含ioc,也不依赖具体ioc实现,可以使用asp.net core的内置依赖注入或者任何兼容asp.net core的第三方ioc来继承aspectcore到asp.netcore应用中
-
高性能的异步拦截系统
-
灵活的配置系统
-
基于service的而非基于实现类的切面构造
-
支持扩平台的asp.net core环境
使用aspectcore
从nuget中安装aspectcore
aspectcore.extensions.dependencyinjection
package
pm> install-package aspectcore.extensions.dependencyinjection
下面我创建了一个api应用程序.
nuget安装
aspectcore.configuration
package
pm> install-package aspectcore.configuration
下面我新建了一个拦截器 custominterceptorattribute,继承abstractinterceptorattribute(一般情况下继承他即可),他实现iinterceptor接口aspectcore默认实现了基于
attribute
的拦截器配置。/// <summary> /// 自定义拦截器 /// </summary> public class custominterceptorattribute : abstractinterceptorattribute { /// <summary> /// 实现抽象方法 /// </summary> /// <param name="context"></param> /// <param name="next"></param> public override async task invoke(aspectcontext context, aspectdelegate next) { try { console.writeline("执行之前"); await next(context);//执行被拦截的方法 } catch (exception) { console.writeline("被拦截的方法出现异常"); throw; } finally { console.writeline("执行之后"); } } }
定义
icustomservice
接口和它的实现类customservice
:public interface icustomservice { datetime getdatetime(); } public class customservice : icustomservice { public datetime getdatetime() { return datetime.now; } }
在valuescontroller注入icustomservice
[route("api/[controller]")] [apicontroller] public class valuescontroller : controllerbase { private readonly icustomservice _icustomserveice; public valuescontroller(icustomservice icustomservice) { this._icustomserveice = icustomservice; } // get api/values [httpget] public datetime get() { return _icustomserveice.getdatetime(); } }
注册icustomservice,并创建代理容器
public iserviceprovider configureservices(iservicecollection services) { services.addtransient<icustomservice,customservice>(); services.addmvc(); //全局拦截器。使用configuredynamicproxy(action<iaspectconfiguration>)的重载方法,其中iaspectconfiguration提供interceptors注册全局拦截器: services.configuredynamicproxy(config=> { config.interceptors.addtyped<custominterceptorattribute>(); }); services.addmvc().setcompatibilityversion(compatibilityversion.version_2_2); return services.buildaspectinjectorprovider(); }
作为服务的全局拦截器。在
configureservices
中添加:services.addtransient<custominterceptorattribute>(provider => new custominterceptorattribute());
作用于特定
service
或method
的全局拦截器,下面的代码演示了作用于带有service
后缀的类的全局拦截器:services.configuredynamicproxy(config => { config.interceptors.addtyped<custominterceptorattribute>(method => method.declaringtype.name.endswith("service")); });
通配符拦截器,匹配后缀为service
services.configuredynamicproxy(config => { config.interceptors.addtyped<custominterceptorattribute>(predicates.forservice("*service")); });
在aspectcore中提供
nonaspectattribute
来使得service
或method
不被代理:[nonaspect] datetime getdate();
全局配置忽略条件
services.configuredynamicproxy(config => { //namespace命名空间下的service不会被代理 config.nonaspectpredicates.addnamespace("namespace"); //最后一级为namespace的命名空间下的service不会被代理 config.nonaspectpredicates.addnamespace("*.namespace"); //icustomservice接口不会被代理 config.nonaspectpredicates.addservice("icustomservice"); //后缀为service的接口和类不会被代理 config.nonaspectpredicates.addservice("*service"); //命名为method的方法不会被代理 config.nonaspectpredicates.addmethod("method"); //后缀为method的方法不会被代理 config.nonaspectpredicates.addmethod("*method"); });
aspectcore
https://github.com/dotnetcore/aspectcore-framework
测试项目地址
https://github.com/fhcodegit/dotnetaspectcore/tree/master