在.NET Core中三种实现“可插拔”AOP编程方式(附源码)
一看標(biāo)題肯定會聯(lián)想到使用動態(tài)編織的方式實現(xiàn)AOP編程,不過這不是作者本文討論的重點。
本文討論另外三種在netcore中可實現(xiàn)的方式,Filter(過濾器,嚴(yán)格意義上它算是AOP方式),DynamicProxy(動態(tài)代理方式,JAVA上早已不是新鮮事),Middleware(netcore中間件所實現(xiàn)的AOP方式)
?
什么是AOP編程
在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP的延續(xù),是軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對業(yè)務(wù)邏輯的各個部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。
換白話文就是:保證開閉原則的前提下,不修改某一個模塊(或函數(shù))的任何一行代碼,從而實現(xiàn)對該模塊的橫向擴(kuò)展。
可插拔:即使拋棄AOP,核心內(nèi)容仍然可以運行,降低耦合,提高可重用。
?
創(chuàng)建一個“能說你好,某某某”的ASP .NET CORE WebApi項目
創(chuàng)建項目步驟此處略過,呵呵。
我們假定一個最簡單的“Say Hello”作為項目需求,通過URL傳遞姓名,再返回“hello {name}”。因此創(chuàng)建一個簡單模型PeopleModel,創(chuàng)建一個接口ISay,并用Say實現(xiàn)ISay中的“hello {name}”功能。
?
1 public interface ISay 2 { 3 PeopleModel SayHello(PeopleModel peopleModel); 4 } 1 public class Say : ISay 2 { 3 public PeopleModel SayHello(PeopleModel peopleModel) 4 { 5 peopleModel.Name = $"hello {peopleModel.Name}"; 6 return peopleModel; 7 } 8 } 1 public class PeopleModel 2 { 3 public string Name { get; set; } = ""; 4 public int Age { get; set; } 5 public int Sex { get; set; } 6 }?
再創(chuàng)建一個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方式
動態(tài)代理的方式在JAVA上很早就出現(xiàn)了,比如在Spring框架里面。而NET中利用Autofac和Castle這兩個框架同樣也可以實現(xiàn)動態(tài)代理。
需要用到的框架如下:
Autofac:提供容器控制 Autofac.Extensions.DependencyInjection:對autofac依賴注入進(jìn)行擴(kuò)展 Autofac.Extras.DynamicProxy:對autofac動態(tài)代理進(jìn)行擴(kuò)展Castle.Core:使用動態(tài)代理的實現(xiàn)
相信autofac很多朋友都不陌生了,而配合Castle框架就能實現(xiàn)動態(tài)代理模式,我們新建一個攔截器類,名為InjectInterceptor,而且必須要實現(xiàn)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 }當(dāng)繼承IInterceptor接口時,必須要實現(xiàn)Intercept虛方法,該方法將傳遞IInvocation接口參數(shù),調(diào)用Proceed函數(shù)將會實現(xiàn)方法體以外的函數(shù),就是切面以外的函數(shù)。使用時只需要通過特性即可實現(xiàn)AOP方式,我們稍微修改一下Say這個類,增加一句話:[Intercept(typeof(InjectInterceptor))]
當(dāng)然,還需要在autofac中實現(xiàn)注冊才行,代碼如下:
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方式
?中間件不僅可以實現(xiàn)自定義管道,還也可以作為netcore invoke的AOP編程。我們先建立一個對ApplicationBuilder的擴(kuò)展類
1 public static class InterceptHandler 2 { 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 }運行結(jié)果如下
?
總結(jié)一下
在NETCORE中可以使用AOP的方式有很多很多,包括國內(nèi)優(yōu)秀的開源框架asp.netcore同樣可以實現(xiàn)AOP編程模式。
筆者所提供的三種AOP方式可適用如下
Filter:身份驗證,參數(shù)驗證,處理耗時等等WEB處理級的服務(wù)。
DynamicProxy:功能模塊之間的解耦和重用服務(wù)。
Middleware:Request和Response之間建立的通信等底層服務(wù),必要時還可以實現(xiàn)自定義管道。
?
感謝閱讀!
?
源碼地址:https://github.com/steveleeCN87/C-.three.aop.programming
轉(zhuǎn)載于:https://www.cnblogs.com/SteveLee/p/three_aop_programming.html
總結(jié)
以上是生活随笔為你收集整理的在.NET Core中三种实现“可插拔”AOP编程方式(附源码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sqli-labs(十三)(hpp)
- 下一篇: XML相关的安全漏洞-XXE,XPATH