在軟件業,AOP爲Aspect Oriented Programming的縮寫,意爲:面向切面編程,經過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,是函數式編程的一種衍生範型。利用AOP能夠對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度下降,提升程序的可重用性,同時提升了開發的效率。編程
在.NET Core中比較好的AOP框架有一個叫作Aspect的這樣的一個框架, 它是一個國產的!如何引入AspectCore? 能夠直接nuget。瀏覽器
這AspectCore中須要建立一個攔截器通常繼承自 AbstractInterceptorAttribute。而且實現它的 Invoke 方法 。框架
其中第一個參數是上下文,next是執行的委託方法,經過這個委託能夠執行被攔截的方法。異步
//每一個被攔截的方法中執行 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"); } }
首先咱們能夠建立一個須要被代理攔截的類(必須是public方法是虛方法且被標記,也必須使用MVC中的Filter命名規範)。這個方法也能夠是異步的!async
public class Person { [CustomInterceptor] public virtual void Say(string msg) { Console.WriteLine("service calling..."+msg); } }
如何進行代理? 須要經過ProxyGeneratorBuilder 來代理對象,注意 p 指向的對象是 AspectCore 生成的 Person 的動態子類的對象,直接 new Person是沒法被攔截的。ide
static void Main(string[] args) { ProxyGeneratorBuilder proxyGeneratorBuilder = new ProxyGeneratorBuilder(); using (IProxyGenerator proxyGenerator = proxyGeneratorBuilder.Build()) { Person p = proxyGenerator.CreateClassProxy<Person>(); p.Say("zaranet"); } }
上面說到咱們不能夠直接new這個person,那如今咱們調試一下,一探究竟!!!咱們看看這個p是個什麼類型。函數式編程
噫?爲何這個p不是AspectPollyIdn.Person?而是AspectCore.DynamicGenerated.Person?不妨把這個p的父類給打印出來,來瞅瞅。函數
static void Main(string[] args) { ProxyGeneratorBuilder proxyGeneratorBuilder = new ProxyGeneratorBuilder(); using (IProxyGenerator proxyGenerator = proxyGeneratorBuilder.Build()) { Person p = proxyGenerator.CreateClassProxy<Person>(); Console.WriteLine(p.GetType().BaseType); p.Say("zaranet"); } }
如今的對象是咱們了,也就是它的父類,那這個時候你就絕對要明白了,爲何咱們的被代理類是虛方法,也就是說它用子類類重寫了咱們被代理類的虛方法,也就實現了AOP,那麼呢這也就是Aspect.Core的原理。大概簡單的就是這樣。post
如今你已經瞭解了AspectCore的原理了,但回頭發現每次來建立這些對象都很是繁瑣,咱們只想去使用AspectCore經過CreateClassProxy()來建立咱們想要的代理對象,那麼如今咱們能夠使用AspNetCore的依賴注入解決這個問題。測試
首先呢,咱們引用AspectCore.Extensions.DependencyInjection,這是AspectCore給咱們的一個DI框架。再把Startup中的ConfigureServices進行改造。
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddSingleton<Person>(); return services.BuildAspectInjectorProvider(); }
隨便建立一個類 繼承與AbstractInterceptorAttribute ,重寫方法,再添加一個Person。
public class Person { [CustomInterceptor] public virtual void Say(string msg) { // } }
在API中重載進行依賴注入。下面咱們進行postman進行測試,由於已經關閉了瀏覽器瀏覽。
private Person p; public ValuesController(Person p) { this.p = p; }
OK,成功。