前言
上一篇文章我们讲了怎么使用 NET.AutoApi
这个组件来动态生成webapi接口,让我们不需要创建控制器去转发业务层代码。这篇文章主要是讲解NET.AutoApi
底层是怎么实现动态生成webapi接口
我们回顾下- NET.AutoApi
最终的效果
NET.AutoApi内部原理
其实NET.AutoApi内部是借助于mvc抛出来的扩展,进行动态配置webapi的,主要有以下这么几个地方
- 将当前程序集添加进ApplicationPartManager类中的ApplicationParts集合中
- 增加ApplicationModelConvention处理ApplicationModel,动态增加路由特性等
NET.AutoApi原理之源码浅析详解
其实NET.AutoApi 是基于 AspNet Mvc Core 的
builder.Services.AddControllers();
和app.MapControllers();
去做的,微软留下了很多支持自定义扩展的地方,所以我们看下这两个方法中它干了些啥。注意:我这边只挑出NET.AutoApi
中所用到的地方说,毕竟 mvc 的源码很长
builder.Services.AddControllers();
- 第一点,
AddControllers
内部会调用AddMvcCore
。做的第一件事就是将当前启动程序集放到ApplicationPartManager
类的ApplicationParts
集合中
-
第二点:上图中的
ConfigureDefaultFeatureProviders
方法,请记住ApplicationPartManager对象中的这个集合FeatureProviders
,以及这个类ControllerFeatureProvider
注意FeatureProviders集合以及ControllerFeatureProvider,这个ControllerFeatureProvider类的作用是:用于找出(过滤)程序集(ApplicationParts集合)中的控制器类(PS:那么我们只需要把我们的程序集添加到ApplicationParts集合中,然后增加一个FeatureProvider,可以将任何程序集中的类型,都添加为控制器类)
-
第三点,添加一些若干服务注入,我这边只列举出我们所需的,大家有兴趣自己去看源码
- MvcOptions:这个配置内有一个我们需要的东西,
Conventions
集合属性,
这个
IApplicationModelConvention
集合,可以对控制器类型和方法进行操作,赋予它路由及其它信息 - MvcOptions:这个配置内有一个我们需要的东西,
- services.TryAddSingleton
():这个类很重要,它是将我们的控制器类型,转换成 ApplicationModel
ApplicationModel内包含了,每个控制器类的元属性(方法,路由信息、过滤器、特性标签等等),大家注意:这里会调用MvcOptions中的Conventions集合的Apply方法,我们可以自行添加Convention,这个时候可以将任何类都动态赋予路由等元属性,那么我们可以给一些原本不是控制器类型的类,添加路由信息,让他具备控制器的特性。
services.TryAddSingleton<IActionDescriptorCollectionProvider, DefaultActionDescriptorCollectionProvider>();
和Transient<IActionDescriptorProvider, ControllerActionDescriptorProvider>()
这个
DefaultActionDescriptorCollectionProvider
的类做了两个事,
- 他会调用ApplicationModelFactory类的方法,将控制器类集合,转换成ApplicationModel。
- 然后又将ApplicationModel转换成ActionDescriptor集合
app.MapControllers();
- 开启一个订阅
- 将控制器方法,转换成Endpoint对象(内部是一个RequestDelegate)
- ControllerActionInvoker内部,这个类内部包含了整个请求流程处理,感兴趣的朋友自己去看源码,我这就不绕进去了。