ABP之动态WebAPI
ABP之动态WebAPI
ABP的动态WebApi实现了直接对服务层的调用(其实病没有跨过ApiController,只是将ApiController公共化,对于这一点的处理类似于MVC,对服务端的 调用没有跨过HttpHandler一样),这样不仅减少了ApiController的开发,也更能体现驱动领域设计的层结构。
对WebApi服务的替换与路由配置
AbpWebApiModule是Abp.Web.Api的模块类,该类中定义InitializeAspNetServices,InitializeRoutes两个方法,并且在模块的Initialize方法中执行,这两个方法分别是对WebApi的服务的替换与路由的配置,。这两处对WebApi的变更才使得直接调用服务层成为可能。
对服务的分析与缓存
再对服务信息的存储上,作者提供了DynamicApiControllerInfo,DynamicApiActionInfo(源码中的DynamicApiMethodInfo.cs),其中DynamicApiControllerInfo包含了一DynamicApiActionInfo集合。
在执行AbpHttpControllerSelector, AbpApiControllerActionSelector, AbpControllerActivator的时候,系统已经在初始化的时候对服务层进行了分析与缓存。
在作者给的Demo SimpleTaskSystem下有一模块类SimpleTaskSystemWebApiModule
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[DependsOn(typeof(AbpWebApiModule))] //We declare depended modules explicitlypublic class SimpleTaskSystemWebApiModule : AbpModule{ public override void Initialize() { //This code is used to register classes to dependency injection system for this assembly using conventions. IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); //Creating dynamic Web Api Controllers for application services. //Thus, 'web api layer' is created automatically by ABP. DynamicApiControllerBuilder .ForAll<IApplicationService>(Assembly.GetAssembly(typeof (SimpleTaskSystemApplicationModule)), "tasksystem") .Build(); }} |
在这里是使用到了DynamicApiControllerBuilder,这个类主要是对服务接口进行一个注册,再由IBatchApiControllerBuilder按照注册的服务接口对提供的程序集进行分析。
DynamicApiControllerBuilder提供的ForAll只是返回的一个IBatchApiControllerBuilder实现对象
|
1
2
3
4
|
public static IBatchApiControllerBuilder<T> ForAll<T>(Assembly assembly, string servicePrefix){ return new BatchApiControllerBuilder<T>(assembly, servicePrefix);} |
这个方法为BatchApiControllerBuilder提供了服务接口与服务接口与需要分析的程序集,以及服务地址前缀。
BatchApiControllerBuilder从程序集中获取实现服务接口的非抽象类。BatchApiControllerBuilder再通过DynamicApiControllerBuilder将这些类与服务名信息传递给IApiControllerBuilder。
IApiControllerBuilder将通过服务类生成DynamicApiControllerInfo,再将IApiControllerBuilder存储于DynamicApiControllerManager中,同时分析服务类,将公开非静态方法作为action,存储到DynamicApiControllerManager.Actions
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
internal class ApiControllerBuilder<T> : IApiControllerBuilder<T>{ /// <summary> /// Name of the controller. /// </summary> private readonly string _serviceName; /// <summary> /// List of all action builders for this controller. /// </summary> private readonly IDictionary<string, ApiControllerActionBuilder<T>> _actionBuilders; /// <summary> /// Action Filters to apply to the whole Dynamic Controller. /// </summary> private IFilter[] _filters; /// <summary> /// Creates a new instance of ApiControllerInfoBuilder. /// </summary> /// <param name="serviceName">Name of the controller</param> public ApiControllerBuilder(string serviceName) { if (string.IsNullOrWhiteSpace(serviceName)) { throw new ArgumentException("serviceName null or empty!", "serviceName"); } if (!DynamicApiServiceNameHelper.IsValidServiceName(serviceName)) { throw new ArgumentException("serviceName is not properly formatted! It must contain a single-depth namespace at least! For example: 'myapplication/myservice'.", "serviceName"); } _serviceName = serviceName; _actionBuilders = new Dictionary<string, ApiControllerActionBuilder<T>>(); foreach (var methodInfo in DynamicApiControllerActionHelper.GetMethodsOfType(typeof(T))) { _actionBuilders[methodInfo.Name] = new ApiControllerActionBuilder<T>(this, methodInfo); } } /// <summary> /// The adds Action filters for the whole Dynamic Controller /// </summary> /// <param name="filters"> The filters. </param> /// <returns>The current Controller Builder </returns> public IApiControllerBuilder<T> WithFilters(params IFilter[] filters) { _filters = filters; return this; } /// <summary> /// Used to specify a method definition. /// </summary> /// <param name="methodName">Name of the method in proxied type</param> /// <returns>Action builder</returns> public IApiControllerActionBuilder<T> ForMethod(string methodName) { if (!_actionBuilders.ContainsKey(methodName)) { throw new AbpException("There is no method with name " + methodName + " in type " + typeof(T).Name); } return _actionBuilders[methodName]; } /// <summary> /// Builds the controller. /// This method must be called at last of the build operation. /// </summary> public void Build() { var controllerInfo = new DynamicApiControllerInfo(_serviceName, typeof(DynamicApiController<T>), _filters); foreach (var actionBuilder in _actionBuilders.Values) { if (actionBuilder.DontCreate) { continue; } controllerInfo.Actions[actionBuilder.ActionName] = actionBuilder.BuildActionInfo(); } IocManager.Instance.IocContainer.Register( Component.For<AbpDynamicApiControllerInterceptor<T>>().LifestyleTransient(), Component.For<DynamicApiController<T>>().Proxy.AdditionalInterfaces(new[] { typeof(T) }).Interceptors<AbpDynamicApiControllerInterceptor<T>>().LifestyleTransient() ); DynamicApiControllerManager.Register(controllerInfo); LogHelper.Logger.DebugFormat("Dynamic web api controller is created for type '{0}' with service name '{1}'.", typeof(T).FullName, controllerInfo.ServiceName); }} |
ABP之动态WebAPI的更多相关文章
- ABP源码分析三十五:ABP中动态WebAPI原理解析
动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能, ...
- ABP之动态WebAPI(一)
ABP的动态WebApi实现了直接对服务层的调用(其实病没有跨过ApiController,只是将ApiController公共化,对于这一点的处理类似于MVC,对服务端的 调用没有跨过HttpHan ...
- ABP中动态WebAPI原理解析
ABP中动态WebAPI原理解析 动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类 ...
- ABP之动态WebAPI(二)
HttpControllerDescriptor与HttpActionDescriptor HttpControllerDescriptor封装了某个HttpController类型的元数据,我们可以 ...
- 动态WebApi
动态WebApi实现了直接对Service的调用,其实没有跨过ApiController,只是我们自己创建出ApiController 实现主要分以下几步 一 对默认WebApi服务的替换 ApiGl ...
- ABP项目中使用Swagger生成动态WebAPI
本文是根据角落的白板报的<使用ABP实现SwaggerUI,生成动态webapi>一文的学习总结,感谢原文作者角落的白板报. 1 安装Swashbuckle.core 1.1 选择WebA ...
- 最新版ABP 动态WebAPI 日期转json带T的解决方案| ABP DateTIme Json format
ABP动态webapi返回的json数据中,日期时间带T还有毫秒数的问题,在以往的版本中可以使用下面方法解决: 在XXXAbpWebApiModule中加上下面的代码: 很老的很老的版本有效: pub ...
- [ABP框架]动态web Api的拦截用法。
先进行配置 首先这种需求,一般发生在APP端,我们给APP,不会给所有项目系统的接口给他们用.我们系统有200个接口,但是APP的需求只会用20个.那么这个需求也就应运而生了. 以上为API文件夹中为 ...
- ASP.NET Core 奇淫技巧之动态WebApi
一.前言 接触到动态WebApi(Dynamic Web API)这个词的已有几年,是从ABP框架里面接触到的,当时便对ABP的这个技术很好奇,后面分析了一波,也尝试过从ABP剥离一个出来作为独立组件 ...
随机推荐
- JavaEE SSH集成框架(两) struts2 本地加载dtd文件,action组态
1. 载入中struts2的dtd文件.使struts.xml网络无法验证,和eclipse有技巧 在src在创建struts.xml: <? xmlversion="1.0" ...
- (转)mvn clean install 与 mvn install 的区别(为啥用clean)
之前写代码的过程中曾经遇到过问题,用mvn install后,新改的内容不生效,一定要后来使用mvn clean install 才生效,由于之前没有做记录,以及记不清是什么情况下才会出现的问题,于是 ...
- c#中的属性
在C#中我们可以很自由的访问共有字段,但有时我们可能需要某字段只能读或者写,或在改变字段值得时候做一些其他事情,显然这些仅仅依靠字段是无法实现的,于是便有了属性. 1.基本用法 c#中的属性由属性作用 ...
- 让c#的exe只要被修改就无法运行,支持混淆和数字证书
原文:让c#的exe只要被修改就无法运行,支持混淆和数字证书 首先用sdk的sn工具或者makecert工具生成公钥和密钥,推荐makecert,做自己的证书,我做了一个受信任的根证书放在受信任的根证 ...
- TCP连接建立过程中为什么需要“三次握手”(转)
传输控制协议(Transmission Control Protocol, TCP)是一种面向连接的.可靠的.基于字节流的运输层(Transport layer)通信协议.是专门为了在不可靠的互联网络 ...
- 并发编程实践三:Condition
Condition实例始终被绑定到一个锁(Lock)上.Lock替代了Java的synchronized方法,而Condition则替代了Object的监视器方法,包含wait.notify和noti ...
- iOS_67控件外观对照
iOS 7 button无边框,操作栏透明,控制器全屏 Tab Bar 对照 iOS 7 ...
- 玩转Web之JavaScript(二)-----javaScript语法总结(二) 涉及Date与数组的语法
Date: document.write(document.lastModified) 网页最后一次更新时间 a=new Date(); //创建 a 为一个新的时期象 y=a.getY ear( ...
- POJ3581:Sequence(后缀数组)
Description Given a sequence, {A1, A2, ..., An} which is guaranteed A1 > A2, ..., An, you are to ...
- 2014 ACM湖南匹配10会议省赛
2014湖南游戏..... 1:牡丹江Regional有些球队没来的冲突 2:题目比較水 3:队友神勇发挥 最终在开局不利的情况下完毕了翻盘,拿到了第二名.....没有抓住机会顺势夺冠还是非常遗憾的. ...