• 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();
                //全局拦截器。使用AddDynamicProxy(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]

  • 相关阅读:
    docker 镜像管理
    docker 常用操作
    docker 简单介绍与安装
    emacs 缩进
    stl标准库 iterator_traits
    emacs semantic,speedbar,gdb汇总
    在emacs 里使用gdb
    emacs speedbar功能介绍
    前端基础之BOM和DOM
    modules模块
  • 原文地址:https://www.cnblogs.com/yyfh/p/11496033.html
Copyright © 2020-2023  润新知