標籤:過濾 web 切面 console services iap 提高 耦合 之間
一看標題肯定會聯想到使用動態編織的方式實現AOP編程,不過這不是作者本文討論的重點。
本文討論另外三種在netcore中可實現的方式,Filter(過濾器,嚴格意義上它算是AOP方式),DynamicProxy(動態代理方式,JAVA上早已不是新鮮事),Middleware(netcore中介軟體所實現的AOP方式)
什麼是AOP編程
在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過先行編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,也是Spring架構中的一個重要內容,是函數式編程的一種衍生範型。利用AOP可以對商務邏輯的各個部分進行隔離,從而使得商務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
換白話文就是:保證開閉原則的前提下,不修改某一個模組(或函數)的任何一行代碼,從而實現對該模組的橫向擴充。
可插拔:即使拋棄AOP,核心內容仍然可以運行,降低耦合,提高可重用。
建立一個“能說你好,某某某”的ASP .NET CORE WebApi項目
建立項目步驟此處略過,呵呵。
我們假定一個最簡單的“Say Hello”作為項目需求,通過URL傳遞姓名,再返回“hello {name}”。因此建立一個簡單模型PeopleModel,建立一個介面ISay,並用Say實現ISay中的“hello {name}”功能。
1 public interface ISay2 {3 PeopleModel SayHello(PeopleModel peopleModel);4 }
1 public class Say : ISay2 {3 public PeopleModel SayHello(PeopleModel peopleModel)4 {5 peopleModel.Name = $"hello {peopleModel.Name}";6 return peopleModel;7 }8 }
1 public class PeopleModel2 {3 public string Name { get; set; } = "";4 public int Age { get; set; }5 public int Sex { get; set; }6 }
再建立一個MVC控制器
1 [Route("api/[controller]")] 2 [ApiController] 3 public class DemoController : ControllerBase 4 { 5 [HttpGet] 6 public PeopleModel Get([FromQuery] PeopleModel peopleModel) 7 { 8 return Say.SayHello(peopleModel); 9 }10 }
很簡單的,不做解釋,以免浪費篇幅。
DynamicProxy方式
動態代理的方式在JAVA上很早就出現了,比如在Spring架構裡面。而NET中利用Autofac和Castle這兩個架構同樣也可以實現動態代理。
需要用到的架構如下:
Autofac:提供容器控制
Autofac.Extensions.DependencyInjection:對autofac依賴注入進行擴充
Autofac.Extras.DynamicProxy:對autofac動態代理進行擴充
Castle.Core:使用動態代理的實現
相信autofac很多朋友都不陌生了,而配合Castle架構就能實現動態代理模式,我們建立一個攔截器類,名為InjectInterceptor,而且必須要實現IInterceptor(該介面在Castle.DynamicProxy中),完整代碼如下:
1 using System; 2 using Castle.DynamicProxy; 3 4 namespace InterceptDemo.Intercepts.Inject 5 { 6 public class InjectInterceptor : IInterceptor 7 { 8 public virtual void Intercept(IInvocation invocation) 9 {10 PreProceed(invocation);11 invocation.Proceed();12 PostProceed(invocation);13 }14 15 private void PreProceed(IInvocation invocation)16 {17 Console.WriteLine($"{DateTime.Now} inject interceptor invoke preproceed"); 18 }19 20 private void PostProceed(IInvocation invocation)21 {22 Console.WriteLine($"{DateTime.Now} inject interceptor invoke postproceed");23 }24 }25 }
當繼承IInterceptor介面時,必須要實現Intercept虛方法,該方法將傳遞IInvocation介面參數,調用Proceed函數將會實現方法體以外的函數,就是切面以外的函數。使用時只需要通過特性即可實現AOP方式,我們稍微修改一下Say這個類,增加一句話:[Intercept(typeof(InjectInterceptor))]
當然,還需要在autofac中實現註冊才行,代碼如下:
var builder = new ContainerBuilder();builder.Populate(services);builder.RegisterType<Say>().As<ISay>().EnableInterfaceInterceptors();builder.RegisterType<InjectInterceptor>();
Filter方式
過濾器的方式就更加簡單了,在ASP.NET架構中,使用過濾器的地方非常非常的多,筆者不作一一介紹,直接貼代碼:
1 public class ActionFilter : ActionFilterAttribute 2 { 3 public override void OnActionExecuting(ActionExecutingContext context) 4 { 5 Console.WriteLine($"{DateTime.Now} on action exceuting"); 6 } 7 8 public override void OnActionExecuted(ActionExecutedContext context) 9 {10 Console.WriteLine($"{DateTime.Now} on action exceuted");11 }12 }
Middleware方式
中介軟體不僅可以實現自訂管道,還也可以作為netcore invoke的AOP編程。我們先建立一個對ApplicationBuilder的擴充類
1 public static class InterceptHandler2 {3 public static IApplicationBuilder UseInterceptMiddleware(this IApplicationBuilder app)4 {5 return app.UseMiddleware<InterceptMiddlware>();6 }7 }
再建立一個中介軟體
1 using System; 2 using System.Threading.Tasks; 3 using Microsoft.AspNetCore.Http; 4 5 namespace InterceptDemo.Intercepts.Middleware 6 { 7 public class InterceptMiddlware 8 { 9 private readonly RequestDelegate _next;10 11 public InterceptMiddlware(RequestDelegate next)12 {13 _next = next;14 }15 16 public async Task Invoke(HttpContext context)17 {18 PreProceed(context);19 await _next(context);20 PostProceed(context);21 }22 23 private void PreProceed(HttpContext context)24 {25 Console.WriteLine($"{DateTime.Now} middleware invoke preproceed");26 }27 28 private void PostProceed(HttpContext context)29 {30 Console.WriteLine($"{DateTime.Now} middleware invoke postproceed");31 }32 }33 }
運行結果如下
總結一下
在NETCORE中可以使用AOP的方式有很多很多,包括國內優秀的開源架構asp.netcore同樣可以實現AOP編程模式。
筆者所提供的三種AOP方式可適用如下
Filter:身分識別驗證,參數驗證,處理耗時等等WEB處理級的服務。
DynamicProxy:功能模組之間的解耦和重用服務。
Middleware:Request和Response之間建立的通訊等底層服務,必要時還可以實現自訂管道。
感謝閱讀!
源碼地址:https://github.com/steveleeCN87/C-.three.aop.programming
在.NET Core中三種實現“可插拔”AOP編程方式(附源碼)