前言
本文介绍另一种学习 ABP 框架的方法, 该方法为正面硬钢学习法...
我们不去官网下载模板, 直接引用 DLL, 直接使用.
webApi 项目创建
首先创建一个 WebApi 项目, 结构如下.
然后 Nuget 搜索 ABP, 安装 ABP 框架.(我这里安装的是 5.1.0, 因为最高版本安装不上)
在安装 ABP 前先检查当前安装的 Microsoft.AspNet.WebApi 版本, 因为 ABP5.1.0 依赖的是 WebApi 的 5.2.7, 如果 WebApi 不是 5.2.7, 在 Nuget 包管理 - 程序包管理器控制台中输入 Update-Package Microsoft.AspNet.WebApi -Version 5.2.7 来升级一下.(Get-Package 查看已安装包的信息)
然后修改 Global.asax, 修改代码如下:
- using Abp.Web;
- using ABPWebApi;
- using System;
- using System.Web;
- [assembly: PreApplicationStartMethod(typeof(PreStarter), "Start")]
- namespace ABPWebApi
- {
- public class WebApiApplication : Abp.Web.AbpWebApplication<SdudentApiServiceModule>
- {
- protected override void Application_Start(object sender, EventArgs e)
- {
- base.Application_Start(sender, e);
- }
- }
- public static class PreStarter
- {
- public static void Start()
- { //WebApiApplication.AbpBootstrapper.PlugInSources.AddToBuildManager();
- }
- }
- }
这里 WebApiApplication 不再继承 System.Web.HttpApplication, 改为继承 ABP 框架下的 Abp.Web.AbpWebApplication; 因此原生框架提供的 Application_Start 不再需要, 代码里重写了 ABP 的 Application_Start, 这样我们就找到了 Application_Start, 可以在启动时做自己想做的事情了.
AbpWebApplication 是个泛型, 要求指定默认启动模块的类, 这里我们先写上 SdudentApiServiceModule, 下面会创建这个类.
在 Global 中, 还使用 PreApplicationStartMethod 做了一些启动预处理, 比如加载一些插件, 当然也可以什么都不做.
如果要加载插件或者做一些其他操作, 则需要再引入 ABP.Web, 因为一些配置的依赖库在这里, 这里同样引用 5.1.0 版本.
因为使用了 ABP 框架, 所以我们不再需要微软提供的默认布局了, 下面我们微软的默认布局文件夹删除; 如下图:
现在我们新建一个类库, 创建一个 SdudentApi 模块, 用来编写可以被 HTTP 访问的接口.
创建完类库后, 我们需要在类库里添加一个自定义类, 来标记, 这个类库是 WebApi 服务模块.
创建 SdudentApiServiceModule 类, 并继承 AbpModule.
很明显 AbpModule 在 SdudentApi 类库是未被引用的, 所以我们要引用一下 ABP 的框架.
因为这个模块是 WebApi, 所以我们直接引用 Abp.Web.Api5.1.0 就可以了.(由于 Abp.Web.API 依赖于 Abp, 所以 Abp 也会被同时引入)
现在我们编辑 SdudentApiServiceModule 类.
因为继承了 AbpModule, 所以我们可以 override 它 PreInitialize,Initialize,PostInitialize,Shutdown; 它们分别是模块初始化前, 中, 后和关闭.(只有被加载和关闭时调用这些方法, 调用 API 方法时, 这些不触发)
下面我们编写下 SdudentApiServiceModule, 代码如下:
- [DependsOn(typeof(Abp.WebApi.AbpWebApiModule))]
- public class SdudentApiServiceModule : AbpModule
- {
- public override void PreInitialize()
- {
- Configuration.Modules.AbpWeb().AntiForgery.IsEnabled = false;
- Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;
- }
- public override void Initialize()
- {
- // 按照约定, ABP 自动注册所有 Repositories, Domain Services, Application Services, MVC 控制器和 Web API 控制器
- //ABP 按照约定注册程序集, 下面代码将告诉 ABP 要注册当前程序集.
- IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
- // 动态 ApiController 创建需要在将当前程序集注册进 ABP 后, 才可以调用
- //WebApi 访问路径默认前缀 API/services,Sdudent 是我们追加的前缀, 可以自定义, 例如 Sdudent/Task
- // 外放成 ApiController 的服务需要继承 ABP 的 IApplicationService 接口, 需要准守命名约定, 这样才能被搜索到 (服务命名约定: 服务名 + AppService, 例如 SearchSdudentAppService)
- Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
- .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(SdudentApiServiceModule)), "Sdudent").Build();
- }
- public override void PostInitialize()
- {
- }
- public override void Shutdown()
- {
- }
- }
首先我们为 SdudentApiServiceModule 添加依赖 [DependsOn(typeof(Abp.WebApi.AbpWebApiModule))], 这是因为, ABP 都是通过 Castle 进行依赖控制反转实例化对象的, 所以, 在实例化 SdudentApiServiceModule 时, 如果它依赖的类没有被装载, 它就会报错, 因为我们在写 WebApi, 所以很明显, 我们依赖 Abp.WebApi.AbpWebApiModule 这个模块.
PreInitialize: 这里我们 Http 请求的简单配置, 还可以继续配置, ABP 配置很多.
Initialize: 这里将当前类装载进 ABP, 同时动态创建了 ApiController.
PostInitialize 和 Shutdown 暂时无操作.
现在我们创建服务 (它们将被转换成 ApiController).
创建接口 ISearchSdudentAppService, 代码如下:
- public interface ISearchSdudentAppService : IApplicationService
- {
- [HttpGet]
- string GetSdudent();
- }
注意接口方法需要加 [HttpGet], 不加的会被默认注册为 Post, 测试时会出现无法访问的问题.
创建服务 SearchSdudentAppService, 代码如下:
- public class SearchSdudentAppService: ISearchSdudentAppService
- {
- public string GetSdudent()
- {
- return "I am a Sdudent";
- }
- }
SdudentApiServiceModule 编写完成, 现在我们运行项目测试一下.
如上图, 访问成功.
Url 解析: 这里我们访问的 URL 是 / API/services/Sdudent/SearchSdudent/GetSdudent.
其中 / API/services 是默认前缀, Sdudent / 是我们自定义前缀, SearchSdudent 是 Controler 名, 它是根据服务名来的, 服务名减去约定名 (SearchSdudentAppService-AppService),GetSdudent 是 Action 名, 就是服务里的方法名.
跨域配置
Nuget 搜索 Microsoft.AspNet.WebApi.Cors, 安装与 Microsoft.AspNet.WebApi 相同版本号的 Cors.
SdudentApiServiceModule 模块的 PreInitialize 方法里追加配置.
- var cors = new EnableCorsAttribute("*", "*", "*");
- GlobalConfiguration.Configuration.EnableCors(cors);
Filter 配置
在 SdudentApiServiceModule 模块创建 ExceptionFilter 类, 代码如下:
- public class ExceptionFilter : IExceptionFilter, ITransientDependency
- {
- public bool AllowMultiple => true;
- public async Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
- {
- await Task.Run(()=>
- {
- if (actionExecutedContext == null)
- {
- return;
- }
- if (actionExecutedContext.Exception == null)
- {
- return;
- }
- // 记录 actionExecutedContext.Exception
- });
- }
- }
在 SdudentApiServiceModule 类的 PostInitialize 里配置 Fliter.
- public override void PostInitialize()
- {
- GlobalConfiguration.Configuration.Filters.Add(new ExceptionFilter());
- }
模块依赖
依照上文, 在创建一个 TeacherApi 模块, 然后修改 Global 的启动模块为 TeacherApiServiceModule, 然后引入 SdudentApi 项目.
然后编写 TeacherApiServiceModule 代码如下:
- [DependsOn(typeof(Abp.WebApi.AbpWebApiModule), typeof(SdudentApiServiceModule))]
- public class TeacherApiServiceModule : AbpModule
- {
- private readonly SdudentApiServiceModule _SdudentApiServiceModule;
- public TeacherApiServiceModule(SdudentApiServiceModule sdudentApiServiceModule)
- {
- _SdudentApiServiceModule = sdudentApiServiceModule;
- }
- public override void PreInitialize()
- {
- Configuration.Modules.AbpWeb().AntiForgery.IsEnabled = false;
- Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;
- }
- public override void Initialize()
- {
- IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
- Configuration.Modules.AbpWebApi().DynamicApiControllerBuilder
- .ForAll<IApplicationService>(Assembly.GetAssembly(typeof(TeacherApiServiceModule)), "Sdudent").Build();
- }
- public override void PostInitialize()
- {
- var ret =_SdudentApiServiceModule.GetSdudent();
- Console.WriteLine(ret);
- }
- public override void Shutdown()
- {
- }
- }
如上代码所示, 我们在 DependsOn 上追加 SdudentApiServiceModule 依赖, 然后在 TeacherApiServiceModule 的构造函数里, 使用 SdudentApiServiceModule 类型参数, 然后运行时参数就会被实例化, 并注入进来.
现在我们访问 TeacherApi 的访问, 把 TeacherApiServiceModule 模块调用起来, 看下模块的 PostInitialize 里, 是否成功调用了 SdudentApiServiceModule 模块的方法.
如上图, 依赖调用成功.
Swagger 配置
Nuget 搜索 Swashbuckle.core.
模块下添加函数
- private void ConfigureSwaggerUi()
- {
- Configuration.Modules.AbpWebApi().HttpConfiguration
- .EnableSwagger(c =>
- {
- c.SingleApiVersion("v1", "文档");
- c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
- })
- .EnableSwaggerUi();
- }
然后在 Initialize() 里调用该函数, 配置完成.
然后运行项目, 输入 swagger/ui/index, 如下图:
代码已经传到 GitHub 上了, 欢迎大家下载.
GitHub 地址: https://github.com/kiba518/ApbWebApi
----------------------------------------------------------------------------------------------------
来源: https://www.cnblogs.com/kiba/p/12524915.html