基于Abp的WebApi容器

 简述 对 Abp的动态web api的改造过程 注册

1. 首先通过反射将《服务类型》通过ApiControllerBuilder 构建成成 DynamicApiControllerInfo
2. 在DynamicApiControllerInfo中同时构建DynamicApiActionInfo
3. Ioc注入DynamicApiController<TService> Tservice就是最开始的《服务类型》
3. 最后将DynamicApiControllerInfo添加到DynamicApiControllerManager,通过ServiceName缓存

执行

1. AbpHttpControllerSelector 通过路由获取出“service” 这个参数即ServiceName
2. 通过ServiceName从DynamicApiControllerManager中获取DynamicApiControllerInfo 的信息
3. 将DynamicApiControllerInfo 放入HttpControllerDescriptor.Properties中,返回DynamicHttpControllerDescriptor给MVC处理流程
4. AbpControllerActivator 通过DynamicApiControllerInfor中的ControllerType激活Controller
5. AbpApiControllerActionSelector 获取HttpControllerDescriptor.Properties中的将DynamicApiControllerInfo 信息
6. AbpApiControllerActionSelector 通过 路由的{action}参数获取 方法名
7. AbpApiControllerActionSelector 在 DynamicApiControllerInfor通过方法名获取DynamicApiActionInfo 的信息
8. 最后返回DyanamicHttpActionDescriptor 给MVC处理流程

改造 Action执行的改造

实际在Abp中 DyanamicHttpActionDescriptor 的 ExecuteAsync 中实际是通过AOP拦截实现的.这里我做了修改

首先将DynamicController改为组合的方式注入IService来作为代理对象如下图

然后执行的时候采用获取IDynamicApiController 的ProxyObject 来使用反射执行

 

其中由于MVC并没有放出ReflectedHttpActionDescriptor.ActionExecutor 这个类型,所以用了点技巧。

支持重载

1. 首先在 DynamicApiControllerInfo 中增加属性 FullNameActions 类型和Actions 一致
2. 然后再初始化的时候同时初始化FullNameActions ,Action的key是Name,FullNameActions 是Method.ToString()[这种包含的信息更多,可作为唯一标识]
3. 最后在客户端调用的时候放到Header即可区分,实现函数重载

支持多个复杂参数

在ParameterBindingRules 中添加规则

//增加服务中多个参数的情况 ApiGlobalConfiguration.Configuration.ParameterBindingRules.Insert(0, descriptor => { if (descriptor.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Get) || descriptor.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Delete)) return null; if (descriptor.ActionDescriptor.GetParameters().Count(item => !item.ParameterType.IsSimpleUnderlyingType()) < 2) return null; if (descriptor.ParameterType.IsSimpleUnderlyingType()) return null; if (descriptor.ParameterType.GetCustomAttribute(typeof(ParameterBindingAttribute)) != null) return null; var config = descriptor.Configuration; IEnumerable<MediaTypeFormatter> formatters = config.Formatters; var validators = config.Services.GetBodyModelValidator(); return new MultiPostParameterBinding(descriptor, formatters, validators); });

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdxjy.html