本文有配套视频:
https://www.bilibili.com/video/av58096866/?p=6
前言
上回《【 .NET Core3.0 】框架之九 || 依赖注入IoC学习 + AOP界面编程初探》咱们说到了依赖注入Autofac的使用,不知道大家对IoC的使用是怎样的感觉,我个人表示还是比较可行的,至少不用自己再关心一个个复杂的实例化服务对象了,直接通过接口就满足需求,当然还有其他的一些功能,我还没有说到,抛砖引玉嘛,大家如果有好的想法,欢迎留言,也可以来群里,大家一起学习讨论。昨天在文末咱们说到了AOP面向切面编程的定义和思想,我个人简单使用了下,感觉主要的思路还是通过拦截器来操作,就像是一个中间件一样,今天呢,我给大家说两个小栗子,当然,你也可以合并成一个,也可以自定义扩展,因为我们是真个系列是基于Autofac框架,所以今天主要说的是基于Autofac的Castle动态代理的方法,静态注入的方式以后有时间可以再补充。
时间真快,转眼已经十天过去了,感谢大家的鼓励,批评指正,希望我的文章,对您有一点点儿的帮助,哪怕是有学习新知识的动力也行,至少至少,可以为以后跳槽增加新的谈资 [哭笑],这些天我们从面向对象OOP的开发,后又转向了面向接口开发,到分层解耦,现在到了面向切面编程AOP,往下走将会是,分布式,微服务等等,技术真是永无止境啊!好啦,马上开始动笔。
![cf244e70b6c7431936f2dd9028eae785.gif](https://i-blog.csdnimg.cn/blog_migrate/d33e79ce749e0e3871e15cdea57cf77e.gif)
一、什么是 AOP 切面编程思想
什么是AOP?引用百度百科:AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。实现AOP主要由两种方式,
一种是编译时静态织入,优点是效率高,缺点是缺乏灵活性,.net下postsharp为代表者(好像是付费了。。)。
另一种方式是动态代理,优点是灵活性强,但是会影响部分效率,动态为目标类型创建代理,通过代理调用实现拦截。
AOP能做什么,常见的用例是事务处理、日志记录等等。
常见的AOP都是配合在Ioc的基础上进行操作,上边咱们讲了Autofac这个简单强大的Ioc框架,下面就讲讲Autofac怎么实现AOP。Autofac的AOP是通过Castle(也是一个容器)项目的核心部分实现的,名为Autofac.Extras.DynamicProxy,顾名思义,其实现方式为动态代理。当然AOP并不一定要和依赖注入在一起使用,自身也可以单独使用。
是不是很拗口,没关系,网上有一个博友的图片,大概讲了AOP切面编程:
说的很通俗易懂的话就是,我们在 service 方法的前边和后边,各自动态增加了一个方法,这样就包裹了每一个服务方法,从而实现业务逻辑的解耦。
AOP,我们并不陌生。可能大家感觉这个切面编程思想之前没有用到过,很新鲜的一个东西,其实不是的,之前我们开发的时候也一直在使用这种思想,那就是过滤器,我们可以想想,我们之前在开发 MVC 的时候,是不是经常要对action进行控制过滤,最常见的就是全局异常处理过滤器,只要有错误,就跳出去,记录日志,然后去一个自定义的异常页面,这个其实就是一个 AOP 的思想,但是这里请注意,这个思想是广义的 AOP 编程思想,今天要说的,是真正意义上的切面编程思想,是基于动态代理的基于服务层的编程思想,也是在以后的开发中使用很多的一种编程思想。
![cf244e70b6c7431936f2dd9028eae785.gif](https://i-blog.csdnimg.cn/blog_migrate/d33e79ce749e0e3871e15cdea57cf77e.gif)
二、AOP 之实现日志记录
首先想一想,如果有这么一个需求,要记录整个项目的接口和调用情况,当然如果只是控制器的话,还是挺简单的,直接用一个过滤器或者一个中间件,还记得咱们开发Swagger拦截权限验证的中间件么,那个就很方便的把用户调用接口的名称记录下来,当然也可以写成一个切面,但是如果想看下与Service或者Repository层的调用情况呢,好像目前咱们只能在Service层或者Repository层去写日志记录了,那样的话,不仅工程大(当然你可以用工厂模式),而且耦合性瞬间就高了呀,想象一下,如果日志要去掉,关闭,修改,需要改多少地方!您说是不是,好不容易前边的工作把层级的耦合性降低了。别慌,这个时候就用到了AOP和Autofac的Castle结合的完美解决方案了。
经过这么多天的开发,几乎每天都需要引入Nuget包哈,我个人表示也不想再添加了,现在都已经挺大的了(47M当然包括全部dll文件),今天不会啦!其实都是基于昨天的两个Nuget包中已经自动生成的Castle组件。请看以下步骤:
1、定义服务接口与实现类
在上一篇文章中,我们说到了使用
AdvertisementServices.cs 和 IAdvertisementServices.cs
这个服务,我们新建两个层,分别包含这两个 cs 文件:
然后我们模拟下数据,再新建一个 Model 层,添加 AdvertisementEntity 实体类
namespace Blog.Core.Model{
public class AdvertisementEntity {
public int id { get; set; } public string name { get; set; } }}
然后在上边的 service 方法中,返回一个List数据:
// 接口 public interface IAdvertisementServices {
int Test(); ListTestAOP(); } // 实现类 public class AdvertisementServices : IAdvertisementServices {
public int Test() {
return 1; } public ListTestAOP() => new List() { new AdvertisementEntity() { id = 1, name = "laozhang" } }; }
2、在API层中添加对该接口引用
还是在默认的控制器——weatherForecastController.cs 里,添加