Autofac实现AOP拦截

本文主要是详解一下在ASP.NET Core中,采用替换后的Autofac来实现AOP拦截。

Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题。AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

引入类库

nuget命令如下:
  1. Install-Package Autofac.Extras.DynamicProxy -Version 4.5.0
复制代码
Autofac实现AOP拦截_第1张图片 

采用Autofac来实现AOP

首先,我们创建一个拦截类,代码如下:

  1. public class AOPTest : IInterceptor
  2.     {
  3.         public ILogger _logger { get; set; }
  4.         public void Intercept(IInvocation invocation)
  5.         {
  6.             _logger.LogWarning("你正在调用方法 "{0}"  参数是 {1}... ",
  7.                invocation.Method.Name,
  8.                string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
  9.             //在被拦截的方法执行完毕后 继续执行           
  10.             invocation.Proceed();
  11.             _logger.LogWarning("方法执行完毕,返回结果:{0}", invocation.ReturnValue);
  12.         }
  13.     }
复制代码
这里,需要继承IInterceptor,然后实现它的Intercept方法..我们直接将拦截内容输出到调试窗(正式项目..请根据业务来操作拦截)..

这里我通过ILogger来记录操作,参考如下:

ASP.NET Core ILogger日志使用教程
https://www.itsvse.com/thread-7565-1-1.html
(出处: 架构师_程序员)

找到我们要拦截的服务,TestService1和TestService2,我们通过两种方式来拦截。

TestService1:通过特性拦截
TestService2:通过配置拦截

代码如下:

  1. public interface IBaseTestService
  2.     {
  3.         string GetString();
  4.     }
  5.     public interface ITestService1: IBaseTestService { }
  6.     public interface ITestService2 : IBaseTestService { }
  7.     public interface ITestService3 : IBaseTestService { }
  8.     [Intercept(typeof(AOPTest))]
  9.     public class TestService1 : ITestService1
  10.     {
  11.         private string str { get; set; }
  12.         public TestService1()
  13.         {
  14.             str = Guid.NewGuid().ToString();
  15.         }
  16.         public string GetString()
  17.         {
  18.             return str;
  19.         }
  20.     }
  21.     public class TestService2 : ITestService2
  22.     {
  23.         private string str { get; set; }
  24.         public TestService2()
  25.         {
  26.             str = Guid.NewGuid().ToString();
  27.         }
  28.         public string GetString()
  29.         {
  30.             return str;
  31.         }
  32.     }
  33.     public class TestService3 : ITestService3
  34.     {
  35.         private string str { get; set; }
  36.         public TestService3()
  37.         {
  38.             str = Guid.NewGuid().ToString();
  39.         }
  40.         public string GetString()
  41.         {
  42.             return str;
  43.         }
  44.     }
复制代码
在Startup编辑方法ConfigureServices,通过配置拦截TestService2服务,如下:

  1. public IServiceProvider ConfigureServices(IServiceCollection services)
  2. {
  3.         services.Configure(options =>
  4.         {
  5.                 // This lambda determines whether user consent for non-essential cookies is needed for a given request.
  6.                 options.CheckConsentNeeded = context => true;
  7.                 options.MinimumSameSitePolicy = SameSiteMode.None;
  8.         });
  9.         services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddControllersAsServices(); ;
  10.         //添加数据库上下文和配置数据库连接字符串
  11.         PanDb.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
  12.         services.AddDbContext();
  13.         var builder = new ContainerBuilder();
  14.         builder.Populate(services);//Autofac.Extensions.DependencyInjection
  15.         builder.RegisterInstance(new LoggerFactory())
  16.                 .As();
  17.         builder.RegisterGeneric(typeof(Logger<>))
  18.                    .As(typeof(ILogger<>))
  19.                    .SingleInstance();
  20.         //注册服务
  21.         builder.Register(c => new AOPTest());
  22.         builder.RegisterType().As().PropertiesAutowired().EnableInterfaceInterceptors();
  23.         builder.RegisterType().As().PropertiesAutowired().EnableInterfaceInterceptors().InterceptedBy(typeof(AOPTest));
  24.         builder.RegisterType().As().PropertiesAutowired();
  25.         //注册所有控制器
  26.         var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
  27.         .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
  28.         builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
  29.         builder.RegisterType().PropertiesAutowired();
  30.         var container = builder.Build();
  31.         var loggerFactory = container.Resolve();
  32.         loggerFactory.AddConsole();
  33.         return new AutofacServiceProvider(container);
  34. }
复制代码
重要的代码就如下3行:

  1. builder.Register(c => new AOPTest());
  2.         builder.RegisterType().As().PropertiesAutowired().EnableInterfaceInterceptors();
  3.         builder.RegisterType().As().PropertiesAutowired().EnableInterfaceInterceptors().InterceptedBy(typeof(AOPTest));
复制代码
这里注意,一定要在你注入的服务后面加上EnableInterfaceInterceptors来开启你的拦截

控制器代码如下:

  1. public class HomeController : Controller
  2.     {
  3.         public ILogger test { get; set; }
  4.         public ITestService1 _testService1 { get; set; }
  5.         public ITestService2 _testService2 { get; set; }
  6.         public ITestService3 _testService3 { get; set; }
  7.         public IActionResult Index()
  8.         {
  9.             test.LogError("https://www.itsvse.com");
  10.             test.LogWarning("访问home index页面!");
  11.             ViewBag.Str1 = _testService1.GetString();
  12.             ViewBag.Str2 = _testService2.GetString();
  13.             ViewBag.Str3 = _testService3.GetString();
  14.             return View();
  15.         }
  16.     }
复制代码
通过dotnet run命令启动项目,访问网址,控制台输出日志如下:

Autofac实现AOP拦截_第2张图片 

QQ截图20190508145507.jpg (124.68 KB, 下载次数: 11)

下载附件

2019-5-8 15:07 上传

 


发现通过aop拦截到的返回值和返回给网页的返回值是一样的,这样,我们就完成了使用Autofac进行AOP拦截。

(完)
autofac,  ioc,  aop,  拦截
 

 

你可能感兴趣的:(Autofac实现AOP拦截)