时隔一年,继续我们的Apworks框架之旅。在接下来的文章中,我将逐渐向大家介绍如何在Visual Studio中结合Apworks框架,使用ASP.NET Web API和MVC来开发面向经典分层架构的应用程序。在这一讲中,我们首先了解一下分层架构的各个“层”,以及所涉及的Visual Studio项目,然后,我们从领域模型开始,在Visual Studio中开始我们的应用程序开发之旅。

说明:虽然现在微软已经发布了Visual Studio 2015,但为了照顾广大的老版本用户,本文及后续文章都会以Visual Studio 2013 with Update 4作为开发工具进行介绍。此外,在某些场景中,会需要用到Visual Studio 2013 Ultimate的部分功能,所以,如果您所使用的Visual Studio不是Ultimate版本的话,您将无法动手实践某些案例,但您仍然可以通过阅读文章来获取所需要的知识。

Apworks的近况

已经有一段时间没有向大家介绍Apworks框架的相关内容了,在最近的半年中,我对Apworks做了一些小的重构,具体内容如下:

  1. 将支持的.NET Framework升级到4.5.1
  2. 开始在IEntity接口上支持泛型ID,这也就意味着在经典分层架构的Apworks应用中,实体键可以开始支持多种原始数据类型了(组合键目前仍不支持),比如整形。这一改动不会对已有的框架产生任何影响,默认的实体键类型仍然是Guid
  3. 开始在Unit Of Work的具体实现,也就是RepositoryContext上支持异步Commit的操作:可以使用CommitAsync来进行异步提交。后续版本会支持更多的异步方法
  4. 更新所依赖的第三方框架到最新版本(当然,在写这篇文章时,这些第三方框架或许又有了版本更新)
  5. 改善了NHibernate Repository的实现
  6. 性能优化

您可以直接点击 https://github.com/daxnet/Apworks 进入Apworks框架的开源主页,也可以使用以下命令获取Apworks的源代码:

git clone https://github.com/daxnet/Apworks.git

案例:个人便签应用

我又一次试图从一个应用案例开始向大家介绍整个事情的来龙去脉,希望能够让大家看清楚并了解到问题的本质。我记得之前也有很多文章我也是举了不少例子,有的文章把例子讲解完了,有的又是半途而废,虎头蛇尾。好吧,不管怎么样,没有案例就无法一步步地将问题解释清楚。毕竟理论也是需要跟实践相结合的。

这个案例是一个个人便签应用。刚开始的时候,我把这个小标题称为《案例:一个简单的个人便签应用》,思索之后将“一个简单的”五个字去掉,我想,简单的东西不是大家想要的,简单的东西大家都会做,听起来似乎甚至不需要任何框架和工具的辅助,就能简简单单地把问题解决掉。我想向大家介绍的是一个完整的企业级应用,它不仅应该实现基本的领域逻辑,更应该包含诸如安全、性能等各个方面的内容,所以,综合起来,这事情就简单不了。

认识我的圈内朋友应该都知道我自己开发了一个基于云的个人笔记系统Cloud Notes,也有一些文章介绍Cloud Notes的技术和开发过程。不错,现在我打算使用的这个案例,它的业务背景跟个人笔记系统很像,但为了介绍技术部分,我会让其业务变得更为简单,也会介绍一些实现RESTful服务的最佳实践,因此,该案例会在技术架构层面与Cloud Notes类似,但也会有些细节上的差异。总而言之,尽量以简洁的形式来说明问题。

本案例涉及的部分包括用户和权限,从业务上看,每个用户可以管理自己的便签,内容就这么多。太复杂了会让人觉得头晕目眩,也会降低本文的可读性。OK,让我们给这个案例起个名字,就叫EasyMemo吧。

理论:分层架构与技术选型

在我以前的博客中,少不了对分层架构的介绍,尤其是在介绍领域驱动设计的时候,还介绍了与之异构的基于事件的命令查询职责分离(CQRS)架构。本案例采用经典分层架构进行开发。在此,我觉得还是有必要把架构图再简单画一下,并且标注我们将要使用的微软技术。这样做一方面可以让大家了解到我们使用了哪些技术,另一方面,在后续的介绍中,也可以让大家看到,我们目前是在讨论整个架构的哪个部分。请参见下图:

可以看到,在整个案例的介绍过程中,我们将会使用Entity Framework 6作为数据存储ORM,后台数据库选用Microsoft SQL Server,领域模型层适配Apworks框架,应用层任务协调使用Apworks框架,而通过ASP.NET Web API 2向外界提供RESTful服务。表现层采用ASP.NET MVC 4加上AngularJS实现,当然会用到Twitter Bootstrap的一些特性,毕竟在标准的ASP.NET MVC模板中,默认安装了Bootstrap的包。

基本架构就这样,接下来,让我们一起动手开始在Visual Studio 2013中搭建我们的EasyMemo项目吧。

实践:开始搭建解决方案

打开Visual Studio 2013,当然,目前我们还不需要使用Ultimate版本,因为解决方案的搭建过程不会涉及任何与Visual Studio 2013 Ultimate相关的特性。为了能让解决方案中各项目的组织更为合理,建议首先在Visual Studio 2013中新建一个空白的解决方案,.NET Framework版本请选择4.5.1,因为今后要用的Apworks框架是基于4.5.1的:

单击“确定”按钮后,Visual Studio就会在【解决方案资源管理器】中显示一个空白的解决方案。接下来,我们就相继往该解决方案中创建以下新项目:

  • EasyMemo.Common:提供包括公共类型以及基础结构层的那些可以适用于其它各层的类型和组件
  • EasyMemo.Domain:包含领域模型的类型,以及这些类型的扩展方法
  • EasyMemo.Repositories:仓储实现库,提供与领域模型对象仓储相关的类型定义以及实现
  • EasyMemo.Services:一个ASP.NET Web API应用程序,用以向外界提供RESTful服务。在【新建项目】对话中选择【Visual C# –> Web】分类,在该分类中选择【ASP.NET Web应用程序】,在弹出的【新建ASP.NET项目】对话框中,选择【Empty】,在【为以下对象添加文件夹和核心引用】分组中,选择Web API:

  • EasyMemo.Web:EasyMemo的主页网站,向用户提供操作界面,接收用户请求,并将请求转发到RESTful服务。在【新建项目】对话中选择【Visual C# –> Web】分类,在该分类中选择【ASP.NET Web应用程序】,在弹出的【新建ASP.NET项目】对话框中,选择【MVC】:

创建完成后,EasyMemo的解决方案中应该包含如下5个项目,每个项目中都只包含了Visual Studio项目模板自带的默认类型:

 

为了能够在编译整个解决方案的时候,让Visual Studio自动下载每个项目所依赖的NuGet包,强烈建议在EasyMemo解决方案上单击鼠标右键,选择【启用NuGet程序包还原】选项:

 

现在,我们就从领域模型的设计开始,一步步地完成整个应用程序的开发。

迈向领域建模的第一步

首先,在EasyMemo.Domain项目上,单击鼠标右键,选择【管理NuGet程序包】,在弹出的对话框的【搜索联机】文本框中,输入关键字【Apworks】,然后在程序包列表中选择【Apworks】并单击【安装】按钮:

在安装时会提示许可协议对话框,单击【我接受】按钮即可。

然后,在EasyMemo.Domain上再新增一个AggregateRoot抽象类,使其实现Apworks中的IAggregateRoot接口:

using System;
using Apworks; public abstract class AggregateRoot : IAggregateRoot
{
public Guid ID { get; set; }
}

再新建一个Account类,使其继承AggregateRoot类,它表示在EasyMemo整个应用程序中的“用户账户”的概念,为了今后的实现更为方便快捷,Account类仅提供以下属性:

/// <summary>
/// 表示EasyMemo中“用户账户”的概念
/// </summary>
public class Account : AggregateRoot
{
/// <summary>
/// 获取或设置账户名。
/// </summary>
public string Name { get; set; } /// <summary>
/// 获取或设置账户密码。
/// </summary>
public string Password { get; set; } /// <summary>
/// 获取或设置邮箱地址。
/// </summary>
public string Email { get; set; } /// <summary>
/// 获取或设置显示名称。
/// </summary>
public string DisplayName { get; set; } /// <summary>
/// 获取或设置账户创建日期。
/// </summary>
public DateTime DateCreated { get; set; } /// <summary>
/// 获取或设置最近一次登录日期。
/// </summary>
public DateTime? DateLastLogon { get; set; }
}

编译EasyMemo.Domain,编译通过,表示我们已经正常安装并引用Apworks程序包了,可以继续对领域模型进行设计了。在下一讲中,我将介绍EasyMemo领域模型的设计。

Apworks框架实战(四):使用Visual Studio开发面向经典分层架构的应用程序:从EasyMemo案例开始的更多相关文章

  1. Apworks框架实战

    Apworks框架实战(一):Apworks到底是什么? Apworks框架实战(二):开始使用 Apworks框架实战(三):单元测试与持续集成 Apworks框架实战(四):使用Visual St ...

  2. Apworks框架实战(一):Apworks到底是什么?

    简介 Apworks是一款基于Microsoft .NET的面向领域驱动的企业级应用程序开发框架,它适用于以领域模型为核心的企业级系统的开发和集成.Apworks不仅能够很好地支持经典的分层架构,而且 ...

  3. 使用Visual Studio开发跨平台的iOS应用程序

    [原文发表地址]Developing cross-platform iOS application using Visual Studio [原文发表时间]2015/6/4 C ++是一种流行的高级编 ...

  4. Apworks框架实战(二):开始使用

    要使用Apworks进行应用程序开发,您需要安装Visual Studio 2012以上的版本(以下简称Visual Studio 2012+),从Apworks 2.5开始,需要Micrsoft.N ...

  5. visual studio开发工具的C#主流控件属性一览表

    visual studio开发工具的C#主流控件属性一览表 详细的介绍了各控制属性的详细中文介绍 C#控件及常用设计整理 1.窗体 1.常用属性 (1)Name属性:用来获取或设置窗体的名称,在应用程 ...

  6. emWin模拟器Visual Studio开发时无法printf打印的问题

    1.emWin模拟器 为了方便用户学习evWin框架,Segger设计了一个PC仿真的工具,可以测试绝大部分GUI的功能,除了方便使用者学习之外,还可以加速项目开发进度.毕竟在PC上用Visual S ...

  7. SharePoint 2013 工作流之Visual Studio开发示例篇

    SharePoint 2013引用了WF4.0 Foundation,支持使用Designer和Visio进行设计,但是功能受限,而Visual Studio可以开发功能更加丰富的工作流,下面我们简单 ...

  8. visual studio 开发linux程序

    VisualGDB支持Linux的原理是,通过ssh连接到Linux系统上通过ssh给linux下达命令 . (类似visualgdb的有windgb  ,这2个都是商业软件.) Visual GDB ...

  9. 解决无法连接到visual studio开发服务器的问题

    今天vs抽风,调试网站出现下图那样: 然后我开始百度搜索 "无法连接到visual studio开发服务器" 出现很多文章: 打开一篇问题,看了里面的内容, 那个解决办法也不是最好 ...

随机推荐

  1. Java中的多态

    1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal {public abstract void Say();} 子类: public class ...

  2. 基于OpenCV的车辆检测与追踪的实现

    最近老师布置了一个作业,是做一个基于视频的车辆检测与追踪,用了大概两周的时间做了一个简单的,效果不是很理想,但抑制不住想把自己的一些认识写下来,这里就把一些网络上的博客整理一下分享给大家,希望帮助到大 ...

  3. 探索ASP.NET MVC5系列之~~~6.Session篇(进程外Session)

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  4. 探索ASP.NET MVC5系列之~~~4.模型篇---包含模型常用特性和过度提交防御

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  5. NET Core-TagHelper实现分页标签

    这里将要和大家分享的是学习总结使用TagHelper实现分页标签,之前分享过一篇使用HtmlHelper扩展了一个分页写法地址可以点击这里http://www.cnblogs.com/wangrudo ...

  6. c#比较两个数组的差异

    将DataTable中某一列数据直接转换成数组进行比较,使用的Linq,要引用命名空间using System.Linq; string[] arrRate = dtRate.AsEnumerable ...

  7. java面向对象中的关键字

    1,super关键字 super:父类的意思 1. super.属性名 (调用父类的属性) 2. super.方法名 (调用父类的方法) 3. super([参数列表])(调用父类的构造方法) 注意: ...

  8. ES6之变量常量字符串数值

    ECMAScript 6 是 JavaScript 语言的最新一代标准,当前标准已于 2015 年 6 月正式发布,故又称 ECMAScript 2015. ES6对数据类型进行了一些扩展 在js中使 ...

  9. ORA-00821: Specified value of sga_target 3072M is too small, needs to be at least 12896M

    在测试PlateSpine克隆的数据库服务器时,由于资源有限,克隆过来的数据库服务器只给了9G的内存,结果在测试时,老是会出现OOMkiller导致宕机,即out of memory killer,是 ...

  10. Linux基础介绍【第三篇】

    更改SSH服务端远程登录的配置 windows服务端的默认远程管理端口是3389,管理员用户是administrator,普通用户是guest.Linux的管理用户是root,普通用户默认有很多个,远 ...