1.什么是AOP

AOP是Aspect Oriented Programming的缩写,意为面向切面编程。是指在编译的时候或者运行期间实现一些功能。将代码切入到类的指定位置上,大部分是方法之前之后

2.为什么使用AOP

  1. 解决重复编码,比如打印日志,记录接口执行时间
  2. 针对业务无关的逻辑处理,比如授权。将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可。
  3. 在不改变原有代码的基础上,从外部切入,实现功能的扩展。
  4. 将思维解放,从而在不同的视角解决问题。

    3.实现

    3.1 过滤器Filter

    作为.NET Core的使用人员,你肯定或多或少的接触过Filter来实现一些功能。比如[IActionFilter](https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.mvc.filters.iactionfilter)[IExceptionFilter](https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.mvc.filters.iexceptionfilter)
    新建ASP.NET Core空项目AopDemo
    image.png
    新建类LoggerFilter继承IActionFilter并实现。 ```csharp using Microsoft.AspNetCore.Mvc.Filters;

namespace AopDemo { public class LoggerFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { System.Console.WriteLine(“这是开始”); }

  1. public void OnActionExecuted(ActionExecutedContext context)
  2. {
  3. System.Console.WriteLine("这是结束");
  4. }
  5. }

}

  1. 新建`HomeController`
  2. ```csharp
  3. using Microsoft.AspNetCore.Mvc;
  4. using System.Threading.Tasks;
  5. namespace AopDemo
  6. {
  7. [Route("[controller]/[action]")]
  8. public class HomeController : ControllerBase
  9. {
  10. [HttpGet]
  11. public Task Go()
  12. {
  13. System.Console.WriteLine("Go");
  14. return Task.CompletedTask;
  15. }
  16. }
  17. }

修改Startup

  1. using Microsoft.AspNetCore.Builder;
  2. using Microsoft.AspNetCore.Hosting;
  3. using Microsoft.Extensions.DependencyInjection;
  4. using Microsoft.Extensions.Hosting;
  5. namespace AopDemo
  6. {
  7. public class Startup
  8. {
  9. public void ConfigureServices(IServiceCollection services)
  10. {
  11. services.AddControllers(options => options.Filters.Add<LoggerFilter>());
  12. }
  13. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  14. {
  15. if (env.IsDevelopment())
  16. {
  17. app.UseDeveloperExceptionPage();
  18. }
  19. app.UseRouting();
  20. app.UseEndpoints(endpoints =>
  21. {
  22. endpoints.MapControllers();
  23. });
  24. }
  25. }
  26. }

在浏览器中输入http://localhost:5000/home/go
image.png

3.2 中间件Middleware

使用中间件,也是一种AOP思想的应用。
继续使用上面的项目,新建类LoggerMiddleware继承IMiddleware

  1. using Microsoft.AspNetCore.Http;
  2. using System;
  3. using System.Diagnostics;
  4. using System.Threading.Tasks;
  5. namespace AopDemo
  6. {
  7. public class LoggerMiddleware : IMiddleware
  8. {
  9. public async Task InvokeAsync(HttpContext context, RequestDelegate next)
  10. {
  11. Stopwatch sw = Stopwatch.StartNew();
  12. await next(context);
  13. sw.Stop();
  14. Console.WriteLine("执行:{0},耗时:{1}", context.Request.Path, sw.Elapsed);
  15. }
  16. }
  17. }

Startup类注入LoggerMiddleware,并使用中间件app.UseMiddleware<LoggerMiddleware>()

  1. using Microsoft.AspNetCore.Builder;
  2. using Microsoft.AspNetCore.Hosting;
  3. using Microsoft.Extensions.DependencyInjection;
  4. using Microsoft.Extensions.Hosting;
  5. namespace AopDemo
  6. {
  7. public class Startup
  8. {
  9. public void ConfigureServices(IServiceCollection services)
  10. {
  11. services.AddControllers(options => options.Filters.Add<LoggerFilter>());
  12. services.AddTransient<LoggerMiddleware>();
  13. }
  14. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  15. {
  16. if (env.IsDevelopment())
  17. {
  18. app.UseDeveloperExceptionPage();
  19. }
  20. app.UseMiddleware<LoggerMiddleware>();
  21. app.UseRouting();
  22. app.UseEndpoints(endpoints =>
  23. {
  24. endpoints.MapControllers();
  25. });
  26. }
  27. }
  28. }

在浏览器中输入http://localhost:5000/home/go
image.png

3.3 动态代理 Dynamic Proxy

Castle

TODO

以上都是在运行期间进行实现功能,也可以使用Fody实现在编译期间将原有功能改变,或在之前之后注入。