• .netcore 中使用开源的AOP框架 AspectCore


    AspectCore Project 介绍

    什么是AspectCore Project ?

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

    为什么要设计AspectCore ?

    在传统.Net Framework和Asp.Net Framework中,我们使用Castle DynamicProxy 或者CLR提供的 Remoting.Proxies 可以轻松的实现 Aop 来分离关注点从而降低业务逻辑和基础框架功能的耦合。然而在Asp.Net Core中,不仅缺乏细粒度的Aop支持(MiddlewareFilter都是Asp.Net Core的内置Aop实现,但仅适合在Web层使用),Castle也迟迟未能友好的支持Asp.Net Core。

    因此 AspectCore 提供了一个全新的轻量级和模块化的Aop解决方案,下面是AspectCore的基本特性:

    • 提供抽象的Aop接口,基于该接口,可以轻松的使用自己的代理类实现替换默认的实现
    • 框架不包含IoC,也不依赖具体的IoC实现,可以使用Asp.Net Core的内置依赖注入或任何兼容 Asp.Net Core的第三方IoC来集成 AspectCore 到 Asp.Net Core 应用程序中
    • 高性能的异步拦截器系统
    • 灵活的配置系统
    • 基于Service的而非基于实现类的切面构造
    • 支持跨平台的Asp.Net Core环境

     上面是一些概念介绍,关于AOP指的是面向切面编辑,其时我们之前用过,只是没注意而已,比如.netcore中的services中的方法,注入到服务中,权限过滤等都可以理解为AOP.

     下面使用aspectcore写一个注入的例子,可以应用到验证权限中。

    •  首先创建一个.netcore api项目,使用nuget添加AspectCore.Core、AspectCore.Extensions.DependencyInjection包的引用,我两个用的是1.2.0版本

    • 创建自定义属性类,继承自AbstractInterceptorAttribute
    using AspectCore.DynamicProxy;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace AspectCore
    {
        public class CustomInterceptorAttribute: AbstractInterceptorAttribute
        {
            public async override Task Invoke(AspectContext context, AspectDelegate next)
            {
                try
                {
                    Console.WriteLine("Before service call");
                    await next(context);
                }
                catch (Exception)
                {
                    Console.WriteLine("Service threw an exception!");
                    throw;
                }
                finally
                {
                    Console.WriteLine("After service call");
                }
            }
    
        }
    }
    • 创建service类,添加属性过滤
    using AspectCore.DynamicProxy;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace AspectCore.Services
    {
    
        public interface ICustomService
        {
            [CustomInterceptor]
            void Call();
        }
        public class CustomService : ICustomService
        {
            public void Call()
            {
                Console.WriteLine("service calling...");
            }
        }
    }
    • 创建Home控制器,添加测试Action
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using AspectCore.Services;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    
    namespace AspectCore.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class HomeController : ControllerBase
        {
          
            private readonly ICustomService _service;
            public HomeController(ICustomService service)
            {
                _service = service;
            }
    
           [HttpGet("getmsg")]
            public  void GetMsg()
            {
               
                _service.Call();
            }
    
        }
    }
    • 在startup中注入服务,主要是ConfigureServices中做了修改
    using System;
    using AspectCore.Configuration;
    using AspectCore.Extensions.DependencyInjection;
    using AspectCore.Injector;
    using AspectCore.Services;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    
    
    namespace AspectCore
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public IServiceProvider ConfigureServices(IServiceCollection services)
            {
                //根据属性注入来配置全局拦截器
                services.ConfigureDynamicProxy(config =>
                {
                    config.Interceptors.AddTyped<CustomInterceptorAttribute>();//CustomInterceptorAttribute这个是需要全局拦截的拦截器
                });
    
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); ;
    
                 services.AddSingleton<ICustomService, CustomService>();
    
                var serviceContainer = services.ToServiceContainer();//容器
                return serviceContainer.Build();
    
            }
               public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseHsts();
                }
    
                app.UseHttpsRedirection();
                app.UseMvc();
            }
        }
    }
    • 最后运行项目,即可查看运行结果,网上有的说只能调用Control中Action方法为virtual方法才能成功,其实是错误的。
    • 目录结构如下

  • 相关阅读:
    MySQL之自增长
    MySQL字符集和校对规则
    关于MySQL安装目录bin下工具的详解
    Linux下载安装配置FTP
    Linux和Windows平台安装MySQL的两种方式
    kali安装linux-header
    Mysql之事务
    Linux之ps命令
    Linux之dd命令
    python爬虫之xpath的基本使用
  • 原文地址:https://www.cnblogs.com/personblog/p/11170675.html
Copyright © 2020-2023  润新知