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 explicitly
public 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的更多相关文章

  1. ABP源码分析三十五:ABP中动态WebAPI原理解析

    动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能, ...

  2. ABP之动态WebAPI(一)

    ABP的动态WebApi实现了直接对服务层的调用(其实病没有跨过ApiController,只是将ApiController公共化,对于这一点的处理类似于MVC,对服务端的 调用没有跨过HttpHan ...

  3. ABP中动态WebAPI原理解析

    ABP中动态WebAPI原理解析 动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类 ...

  4. ABP之动态WebAPI(二)

    HttpControllerDescriptor与HttpActionDescriptor HttpControllerDescriptor封装了某个HttpController类型的元数据,我们可以 ...

  5. 动态WebApi

    动态WebApi实现了直接对Service的调用,其实没有跨过ApiController,只是我们自己创建出ApiController 实现主要分以下几步 一 对默认WebApi服务的替换 ApiGl ...

  6. ABP项目中使用Swagger生成动态WebAPI

    本文是根据角落的白板报的<使用ABP实现SwaggerUI,生成动态webapi>一文的学习总结,感谢原文作者角落的白板报. 1 安装Swashbuckle.core 1.1 选择WebA ...

  7. 最新版ABP 动态WebAPI 日期转json带T的解决方案| ABP DateTIme Json format

    ABP动态webapi返回的json数据中,日期时间带T还有毫秒数的问题,在以往的版本中可以使用下面方法解决: 在XXXAbpWebApiModule中加上下面的代码: 很老的很老的版本有效: pub ...

  8. [ABP框架]动态web Api的拦截用法。

    先进行配置 首先这种需求,一般发生在APP端,我们给APP,不会给所有项目系统的接口给他们用.我们系统有200个接口,但是APP的需求只会用20个.那么这个需求也就应运而生了. 以上为API文件夹中为 ...

  9. ASP.NET Core 奇淫技巧之动态WebApi

    一.前言 接触到动态WebApi(Dynamic Web API)这个词的已有几年,是从ABP框架里面接触到的,当时便对ABP的这个技术很好奇,后面分析了一波,也尝试过从ABP剥离一个出来作为独立组件 ...

随机推荐

  1. 重新想象 Windows 8 Store Apps (2) - 控件之按钮控件: Button, HyperlinkButton, RepeatButton, ToggleButton, RadioButton, CheckBox, ToggleSwitch

    原文:重新想象 Windows 8 Store Apps (2) - 控件之按钮控件: Button, HyperlinkButton, RepeatButton, ToggleButton, Rad ...

  2. OpenVPN-ng,为移动续航的应用层隧道

    VPN,让人觉得它总是做好事的,是逃离监管的途径,其实VPN已经成了逃离监管的唯一代名词.你看,无论是什么技术,IPSec也好,WEB代理也罢,仅仅要是加密了原始信息的技术,都能够叫做VPN,于是乎就 ...

  3. Dom4j分解xml

    package cn.com.guju.util; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingExc ...

  4. LinearLayout具体解释一:LinearLayout的简单介绍

    LinearLayout,中文意思是线性布局.假设你是初学android的,肯定会非常困惑"啥叫布局",啥又叫"线性布局"呢. 有的时候,我尝试用官方的语言去解 ...

  5. JavaScript向select下拉框中加入和删除元素

    JavaScript向select下拉框中加入和删除元素 1.说明 a   利用append()方法向下拉框中加入元素 b   利用remove()方法移除下拉框中最后一个元素 2.设计源代码 < ...

  6. java: org.luaj.vm2.LuaError:XXX module not found lua脚本初始化出错(转)

    我遇到这个错误是因为在引用脚本目录时,设置错了位置.设置成脚本所在目录的上级目录. lua使用和加载初始化方法 在java中使用lua,使用需要引用 luaj-jse-2.0.2.jar 同时需要使用 ...

  7. iOS开展-clang: error: unknown argument: &#39;-websockets&#39;解决方案

    问题: 昨天莫名其妙Xcode自己主动升级,那么今天之前执行project什么时候,不知怎的,他们都获得了. 错误内容: clang: error: unknown argument: '-webso ...

  8. 【Android基础】listview控件的使用(2)-------继承自ListActivity的普通listview

    由于listview在android控件中的重要性,所以android为我们直接封装了一个类ListviewActivity,直接将listview封装在了activity之中,在本篇中,我将介绍在L ...

  9. [cocos2dx注意事项014]一个用于cocos2dx对象智能指针模板

    现在,C++有许多实现智能指针,一个更无所谓.哈. 这种智能指针是专为cocos2dx 2.2.x自定义.主要的易用性,同时必须遵循现有的cocos2dx内存管理.特殊实现这样的智能指针.无需在使用时 ...

  10. MongoDB(三)——CRUD

    MongoDB作为非关系型数据库.还是传统数据库的增删改查有很大的差别的.这里仅仅是将知识点进行了一下提纲挈领,实际用的时候.我们百度一下具体使用方法就可以. 先看大的几个方面: 一.对于里边的插入和 ...