AspectCore Project 介紹 什麼是AspectCore Project ? AspectCore Project 是適用於Asp.Net Core 平臺的輕量級 Aop(Aspect-oriented programming) 解決方案,它更好的遵循Asp.Net Core的模塊化開 ...
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支持(Middleware
和Filter
都是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方法才能成功,其實是錯誤的。
- 目錄結構如下