简介
Apworks是一款基于Microsoft .NET的面向领域驱动的企业级应用程序开发框架,它适用于以领域模型为核心的企业级系统的开发和集成。Apworks不仅能够很好地支持经典的分层架构,而且还能支持基于事件驱动的命令查询职责分离(Command-Query Responsibility Segregation, CQRS)架构。
随着软件系统日趋复杂,构建一套可用的、稳定的、可扩展的、安全的以及高效的系统变得越来越困难。为了解决这样的困难,人们在多年的软件开发过程中积累了不少经验,由其是在大型复杂软件系统方面,面向对象的分析和设计(OOAD)占据着主导地位。由此,Eric Evans将这些经验整理成文,于2004年出版了《领域驱动设计:软件核心复杂性应对之道》一书,世界*软件架构大师Martin Fowler也参与了该书的编撰工作。
在书中,Eric Evans提出了软件的设计与架构应当以领域为核心,而不是数据库或者其它的软件基础结构,因为领域描述了软件所需解决的实际问题。在设计和架构阶段,软件开发人员与领域专家必须建立一套用于交流的“通用语言”,并基于这套语言来共同建立领域模型。整个软件的设计与架构就需要以这个领域模型为中心,这样做不仅能够让开发团队更好地理解业务需求,减少因需求理解和沟通引起的偏差,而且还能使核心部件独立于具体的软件技术实现,为今后的新技术革新和扩展做好充分准备。
领域驱动设计并不是一种特定的模式,也不是一种具体的方法论,它所涵盖的范围相当广泛,比如,面向对象分析与设计的基本原则、测试驱动开发、行为驱动开发、持续集成、敏捷开发、防腐层、界定上下文、分层体系结构模式、读写分离体系结构模式、事件驱动体系结构模式等等,都属于领域驱动设计的讨论范畴。总而言之,所有以领域模型为核心的开发方法、过程与技术,均可认为是领域驱动的。
为了能让这些开发技术、开发方法、以及软件设计原则与模式能够很好地运用到实际项目中,一些面向领域驱动设计的开发框架应运而生,比如Java阵营有非常知名的AxonFramwork和JdonFramework。这些框架对领域驱动设计中所涉及的基本概念和模式都有着很好的支持,这不仅让开发人员能够很方便地开发出专业的、面向领域驱动的软件系统,使得软件系统能够更好地满足客户需求,解决实际的业务问题,而且在安全性、高效性、可扩展性和可维护性方面为软件系统提供保障,大大提高了软件产品的质量。
由于软件需求具有多样性和可变性的特点,往往没法在项目的前期将所有需求完全确定下来,因此,对于日趋复杂的软件系统而言,传统的瀑布开发模型遇到了一定的挑战,而基于迭代的敏捷开发模式相对而言更能有效地解决需求的多样性和可变性所带来的潜在风险。由于迭代的引入,客户能够直接参与到开发过程中,并在迭代中为开发团队提供必要的信息,以保证软件系统本身不会与客户需求相差太远。每一次迭代都会实现一部分客户需求,因此,经过多次迭代,程序代码也会迭代地加入到代码库中。为了确保质量,保证新加入的代码不会影响上一次迭代中所产生的代码,开发团队往往采用持续集成的方式,将代码整合到代码库的主分支上。
持续集成也涵盖了很多技术手段,比如行为驱动开发(BDD)、测试驱动开发(TDD)、自动化测试以及自动化部署等等。而面向对象分析与设计的原则,又对敏捷开发实践提供了很好的技术支撑,相信读过Robert C. Martin所著的《Agile Principals, Patterns and Practices in C#》一书的读者,对这部分会有很深的感触。
由此可见,面向领域驱动设计的开发框架,对敏捷项目的实践也有着很大的帮助,主要表现在以下几个方面:
- 框架在技术上为软件系统提供了完整的模式实践,例如:通过使用AxonFramework或者JdonFramework,可以很方便地实现基于CQRS或者事件驱动的体系结构
- 框架为团队提供了合理可行的软件开发过程模式,例如:利用框架可以很方便快捷地搭建软件系统的解决方案,同时也决定了团队的开发过程和合作方式
- 框架的应用大大提高了团队的开发效率,团队只需要关注与领域相关的业务实现,而无需关注具体的技术实现
- 框架的应用大大降低了出现缺陷(Bug)的几率,因为大多数支撑业务系统的代码都经过了严格的测试和实战的考验
- 框架的应用还为软件系统的整合与集成带来了便捷
Apworks就是一套在.NET下支持面向领域驱动的软件系统开发框架,它具有以下这些特点:
- 基于NuGet Package Manager提供方便快捷的类库包发布方式,开发人员无需关心程序集之间的版本依赖关系
- 提供对领域驱动设计中基本元素的封装。比如:Apworks框架对实体、聚合根、领域事件、领域仓储、事件存储(Event Store)等概念进行了有效的封装和实现
- 提供对现有流行框架的支持。比如:Apworks能够很好地支持AutoMapper、Nancy Framework、ASP.NET MVC以及ASP.NET Web API的使用和开发
- 提供多样化的配置方式。开发人员可以在web/app.config中对Apworks框架进行配置,也可以直接在程序代码中构建配置对象,对框架进行配置。流畅接口(Fluent Interface)的引入,更是为Apworks框架的配置提供了便捷直观的编程体验
- 提供基于Microsoft Patterns & Practices Unity的IoC容器和服务定位器(Service Locator)的实现。不仅如此,开发人员还能根据项目的实际需求对IoC容器和服务定位器进行扩展,使其能够支持更多的Dependency Injection(DI)框架。比如可以很方便地扩展Apworks,使其能够支持基于StructureMap、Ninject等流行的DI框架
- 提供基于Entity Framework和NHibernate两种流行ORM的仓储实现。在应用程序中使用这两种仓储,也就基本涵盖了所有面向关系型数据库的对象持久化方案。Apworks还提供基于MongoDB的NoSQL对象持久化方案,以满足NoSQL解决方案的需求。不仅如此,开发人员还能根据项目的实际需求,对仓储实现进行扩展,以支持更多种类的对象持久化机制
- 提供包括Event Aggregator、MSMQ以及Direct Local Bus的事件和消息派发机制。开发人员能够很方便地将领域事件派发到消息总线上,为应用系统的集成提供便捷。不仅如此,开发人员还能根据项目的实际需求,对消息派发机制进行扩展,甚至可以结合NServiceBus以及Microsoft Biztalk Server等企业级服务总线,实现复杂的消息路由和处理
- 为CQRS架构提供了灵活的、基于SQL Server以及MySQL的事件存储(Event Store),不仅如此,开发人员还能根据项目的实际需求,对事件存储的实现进行扩展,以支持更多种类的存储机制
- 为CQRS架构提供了多样化的领域仓储的实现。开发人员可以根据项目的实际需要来选择或者扩展领域仓储,比如可以选择仅将事件快照作为事件存储的仓储实现,来屏蔽事件回溯的功能,从而达到节省空间的目的
- 为CQRS架构提供了可扩展的事件快照机制。开发人员可以通过简单的配置来决定是否使用事件快照,并定制事件快照的属性和行为
- 提供了对AOP拦截的支持:通过引入Castle Dynamic Proxy,Apworks框架可以很方便地实现面向接口方法的AOP拦截;开发人员还可以根据项目的实际需求,选用由DI框架支持的AOP拦截方案,比如,可以选用Unity Policy Injection Extension作为AOP拦截的解决方案
Apworks为软件系统的设计和开发带来了真正的稳定性、便捷性和灵活性,本文将对Apworks的各个方面进行展示,以向开发人员介绍框架的使用方式。
演示案例
Byteart Retail
在我之前的博客文章中,有一个对Byteart Retail案例进行介绍的系列文章。Byteart Retail就是遵循的面向领域驱动的软件架构模式(经典分层架构)。在Byteart Retail案例推出之后,受到了广大网友的关注,也有网友将Byteart Retail案例与Apworks框架进行整合,以演示Apworks框架对面向领域驱动的企业级软件设计和架构的支持。由Apworks支持的Byteart Retail的案例源代码地址是:https://github.com/daxnet/ByteartRetail_Apworks。需要了解Byteart Retail案例详细信息的读者,请参见:https://github.com/daxnet/ByteartRetail。在此对在线上和线下社区中为Apworks提供支持的网友表示衷心感谢!
Note Service
在Apworks上一个版本发布的时候,我在博客中给出了一个使用Apworks开发的Web API案例,文章题目是:《在ASP.NET MVC Web API中使用Apworks开发第一个HTTP服务》。在文中介绍了配置和使用。在本系列的后续文章中,我将详细介绍Apworks框架的具体应用。
Note Service扩展:对NancyFx的支持
在此对网友止.觀.表示衷心的感谢。该案例详细讲解了Apworks在NancyFx中的应用。原文标题是:《扩展NoteService,支持NancyFx》。
在下一篇文章中,我将介绍Apworks框架的下载、编译和引用。