手工搭建ABP框架(1) - Web项目 - 古霜卡比
source link: http://www.cnblogs.com/skabyy/p/7295533.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
手工搭建ABP框架(1) - Web项目
为了防止不提供原网址的转载,特在这里加上原文链接:
http://www.cnblogs.com/skabyy/p/7295533.html
ABP是 ASP.NET Boilerplate Project 的简称。ABP是基于DDD(领域驱动设计)的框架。ABP包含众多组件,包括依赖注入、动态API、审计日志、权限控制等等。在大部分的ABP教材中,会推荐使用模板(https://aspnetboilerplate.com/Templates)来创建ABP工程。然而在实际使用中(至少在我的情况里)一般都需要手工搭建框架而非使用模板。手工搭建有下面几个好处:
- 模板创建的工程有很多不需要的东西需要调整或删除,手工搭建免去了这些麻烦;
- 手工搭建框架能更自由地根据实际需求进行自定义配置和扩展;
- 手工搭建能帮助你更深入地理解ABP框架。
由于手工搭建ABP框架材料较少,我搭建时踩了不少坑。所以在这里记录一下搭建框架的核心步骤,以免以后重新摸索,同时与大家分享,欢迎拍砖。下面我们以开发一个简单的微博应用为例来展示如何使用ABP框架。
新建VS项目
用VS新建Web MVC项目,项目名称为MyTweet.Web
。同时新建解决方案,解决方案名称为MyTweet
。要注意的一点是ABP只支持.NET 4.6以上版本,所以新建项目时记得选.NET Framework 4.6以上的版本。
接下来,我们遵循DDD的原则,新建以下几个层次的项目:
- 展现层(Presentation),负责用户界面与用户交互。在我们这个应用中,展现层是.NET MVC,包括Controller以及前端代码,实现在项目
MyTweet.Web
中。 - 应用层(Application),负责展现层与领域层之间的协调。实现在项目
MyTweet.Application
中。 - 领域层(Domain),负责业务对象与业务逻辑。实现在项目
MyTweet.Domain
中。 - 基础设施层(Infrastructure),提供一些通用的方法。实现在项目
MyTweet.Infrastructure
中。
新建好项目后,还需要设置引用依赖关系。在此不再赘述。
安装ABP相关的NuGet包
安装Abp
包到所有项目。
安装Abp.Web.Mvc
和Abp.Web.Api
到MyTweet.Web
。
使用的版本均为2.3.0
ABP提供了模块系统。使用模块能方便地管理各个组件的初始化与依赖关系。一般来说,每个项目都会建一个模块。由于本篇只用到了MyTweet.Web
和MyTweet.Application
,所以先只新建这两个模块。
在MyTweet.Application
目录下新建类MyTweetApplicationModule
,并继承自AbpModule
。如图:
模块中的Initialize
方法定义了模块初始化时执行的操作。目前只做了IoC依赖注入的操作。
另外,在MyTweet.Web/App_Start
目录下新建类MyTweetWebModule
,同样也需要继承自AbpModule
,并且,这个模块还需要依赖AbpWebApiModule
(WebAPI需要这个模块),MyTweetApplicationModule
。如图:
最后,为了让程序运行时能识别并执行模块,需要修改入口方法。.NET MVC的入口方法在Global.asax.cs
文件中,如下图,MvcApplication
修改为继承AbpWebApplication<MyTweetWebModule>
,并相应地修改Application_Start
方法。
WebAPI
我们使用WebAPI的方式定义前后端交互的接口。当然,直接使用MVC的方法也是可以的。这里只是单纯为了试用ABP动态WebAPI的用法而使用的WebAPI。
我们将实现两个接口:
GetTweets
接口,GET方法,用于查询出所有微博。CreateTweet
接口,POST方法,用于新增一条微博。
因为我们还没实现数据库访问功能,所以现在还不会真正实现这两个接口,这两个接口现在只让它们返回一些测试数据。
在ABP框架下实现WebAPI十分方便,ABP能够使用反射的方法自动从应用层AppService
的public方法生成WebAPI接口。只需在MyTweetModule
的初始化方法添加代码定义动态ApiController
生成规则:
这些代码会在MyTweetApplicationModule
的程序集中,将所有IApplicationService
的实现类动态生成ApiController
,并且根据方法名对public方法绑定相应的HTTP Method动词。
比如,GetTweets
绑定为GET方法,PutTweet
绑定为PUT方法,其他名称的方法像CreateTweet
绑定为POST方法。
(这里有一个例外,Get开头的方法如果参数是一个object——一个DTO的话,那这个方法会被绑定为POST方法。)
生成的WebAPI接口的访问路径为/api/services/MyTweet/{AppSvcName}/{ActionName}
,其中{AppSvcName}
是IApplicationService
实现类的类名(去掉后缀AppService
),{ActionName}
是方法名。
接下来我们实现GetTweets
和CreateTweet
两个接口:
现在只是简单的让这两个接口随便返回一些结果。GetTweets
是接收一个字符串参数的GET接口,CreateTweet
是接收一个字符串s
、一个整数s
的POST接口(C#与JavaScript对大小写的编码规范不同是一件很烦人的事,幸好ABP框架做了自动转换)。这两个接口的路径分别为/api/services/MyTweet/MyTweet/GetTweets
和/api/services/MyTweet/MyTweet/CreateTweet
。
最后测试一下,运行MyTweet.Web
项目,GET接口直接在浏览器就能访问:
POST接口可以用Postman工具来访问:
大功告成!
你访问API的时候可能会出现"Empty or invalid anti forgery header token"的错误,这是因为某些ABP版本默认开启了CSRF防御。在MyTweetWebModule
的PreInitialize
方法加上下面这行代码关闭CSRF防御就可以了。
Configuration.Modules.AbpWeb().AntiForgery.IsEnabled = false;
Abp Module
最后简要介绍下ABP的模块系统。更详细的讲解可查阅官网的文档https://aspnetboilerplate.com/Pages/Documents/Module-System。
模块主要用来管理系统初始化和关闭时要执行的操作。ABP在系统初始化和关闭时根据模块间依赖关系执行相应的操作。
定义一个模块只需要继承AbpModule
。我们可以用DependsOn
标签来声明模块间的依赖关系(ABP框架会自动解析依赖关系,但建议使用显式的声明)。
一个模块会有如下方法,我们可以重载这些方法来定义模块初始化/关闭时要做的操作:
PreInitialize
:预初始化Initialize
:初始化PostInitialize
:后初始化Shutdown
:关闭
应用启动时会根据模块的依赖顺序进行初始化。比如有模块A和模块B,模块A依赖模块B,那么初始化的执行顺序为:
- B的
PreInitialize
- A的
PreInitialize
- B的
Initialize
- A的
Initialize
- B的
PostInitialize
- A的
PostInitialize
关闭则按照依赖相反顺序:
- A的
Shutdown
- B的
Shutdown
最后还有一个问题:应用启动时,ABP框架如何知道要初始化哪些模块?答案在入口函数方法:
ABP框架解析MyTweetModule
所依赖的模块,按顺序初始化这些模块(包括MyTweetModule
)。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK