欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

dotnetcore实现Aop

程序员文章站 2022-05-18 15:37:51
Asp.NetCore实现Aop,AspectCore实现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());
    

    作用于特定servicemethod的全局拦截器,下面的代码演示了作用于带有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来使得servicemethod不被代理:

       [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