本文主要是详解一下在ASP.NET Core中,采用替换后的Autofac来实现AOP拦截。
Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题。AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。
引入类库
nuget命令如下:
- Install-Package Autofac.Extras.DynamicProxy -Version 4.5.0
复制代码
<ignore_js_op>
采用Autofac来实现AOP
首先,我们创建一个拦截类,代码如下:
- public class AOPTest : IInterceptor
- {
- public ILogger<AOPTest> _logger { get; set; }
- public void Intercept(IInvocation invocation)
- {
- _logger.LogWarning("你正在调用方法 "{0}" 参数是 {1}... ",
- invocation.Method.Name,
- string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
- //在被拦截的方法执行完毕后 继续执行
- invocation.Proceed();
- _logger.LogWarning("方法执行完毕,返回结果:{0}", invocation.ReturnValue);
- }
- }
复制代码
这里,需要继承IInterceptor,然后实现它的Intercept方法..我们直接将拦截内容输出到调试窗(正式项目..请根据业务来操作拦截)..
这里我通过ILogger来记录操作,参考如下:
ASP.NET Core ILogger日志使用教程 https://www.itsvse.com/thread-7565-1-1.html (出处: 架构师_程序员)
找到我们要拦截的服务,TestService1和TestService2,我们通过两种方式来拦截。
TestService1:通过特性拦截 TestService2:通过配置拦截
代码如下:
- public interface IBaseTestService
- {
- string GetString();
- }
- public interface ITestService1: IBaseTestService { }
- public interface ITestService2 : IBaseTestService { }
- public interface ITestService3 : IBaseTestService { }
- [Intercept(typeof(AOPTest))]
- public class TestService1 : ITestService1
- {
- private string str { get; set; }
- public TestService1()
- {
- str = Guid.NewGuid().ToString();
- }
- public string GetString()
- {
- return str;
- }
- }
- public class TestService2 : ITestService2
- {
- private string str { get; set; }
- public TestService2()
- {
- str = Guid.NewGuid().ToString();
- }
- public string GetString()
- {
- return str;
- }
- }
- public class TestService3 : ITestService3
- {
- private string str { get; set; }
- public TestService3()
- {
- str = Guid.NewGuid().ToString();
- }
- public string GetString()
- {
- return str;
- }
- }
复制代码
在Startup编辑方法ConfigureServices,通过配置拦截TestService2服务,如下:
- public IServiceProvider ConfigureServices(IServiceCollection services)
- {
- services.Configure<CookiePolicyOptions>(options =>
- {
- // This lambda determines whether user consent for non-essential cookies is needed for a given request.
- options.CheckConsentNeeded = context => true;
- options.MinimumSameSitePolicy = SameSiteMode.None;
- });
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddControllersAsServices(); ;
- //添加数据库上下文和配置数据库连接字符串
- PanDb.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
- services.AddDbContext<PanDb>();
- var builder = new ContainerBuilder();
- builder.Populate(services);//Autofac.Extensions.DependencyInjection
- builder.RegisterInstance(new LoggerFactory())
- .As<ILoggerFactory>();
- builder.RegisterGeneric(typeof(Logger<>))
- .As(typeof(ILogger<>))
- .SingleInstance();
- //注册服务
- builder.Register(c => new AOPTest());
- builder.RegisterType<TestService1>().As<ITestService1>().PropertiesAutowired().EnableInterfaceInterceptors();
- builder.RegisterType<TestService2>().As<ITestService2>().PropertiesAutowired().EnableInterfaceInterceptors().InterceptedBy(typeof(AOPTest));
- builder.RegisterType<TestService3>().As<ITestService3>().PropertiesAutowired();
- //注册所有控制器
- var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
- .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
- builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
- builder.RegisterType<AOPTest>().PropertiesAutowired();
- var container = builder.Build();
- var loggerFactory = container.Resolve<ILoggerFactory>();
- loggerFactory.AddConsole();
- return new AutofacServiceProvider(container);
- }
复制代码
重要的代码就如下3行:
- builder.Register(c => new AOPTest());
- builder.RegisterType<TestService1>().As<ITestService1>().PropertiesAutowired().EnableInterfaceInterceptors();
- builder.RegisterType<TestService2>().As<ITestService2>().PropertiesAutowired().EnableInterfaceInterceptors().InterceptedBy(typeof(AOPTest));
复制代码
这里注意,一定要在你注入的服务后面加上EnableInterfaceInterceptors来开启你的拦截
控制器代码如下:
- public class HomeController : Controller
- {
- public ILogger<HomeController> test { get; set; }
- public ITestService1 _testService1 { get; set; }
- public ITestService2 _testService2 { get; set; }
- public ITestService3 _testService3 { get; set; }
- public IActionResult Index()
- {
- test.LogError("https://www.itsvse.com");
- test.LogWarning("访问home index页面!");
- ViewBag.Str1 = _testService1.GetString();
- ViewBag.Str2 = _testService2.GetString();
- ViewBag.Str3 = _testService3.GetString();
- return View();
- }
- }
复制代码
通过dotnet run命令启动项目,访问网址,控制台输出日志如下:
<ignore_js_op>
QQ截图20190508145507.jpg (124.68 KB, 下载次数: 11)
下载附件
2019-5-8 15:07 上传
发现通过aop拦截到的返回值和返回给网页的返回值是一样的,这样,我们就完成了使用Autofac进行AOP拦截。
(完) |