目录
- 代码生成
- .netTiers入门
- 当前版本特征
- .netTiers 体系架构
- 企业库应用模块
- NUnit 和 VSTS
- 方案规划
- .netTiersAPI层次
- .netTiers API 的使用者
- 服务层
- 数据访问层
- 实体层
代码生成
CodeSmith是一款模板驱动的代码生成软件,可以生成C#,Visual Basic .NET和你想要的任何语言或文字。作为开发人员,我们工作的许多方面都充满着重复,在这些方面代码生成已经成熟的应对并且变成了必需和受欢迎的方式。代码生成可以帮助我们避免一些失误,一旦你熟练掌握了代码生成的步骤,在代码中生成Bugs的机会就会大大减少。即使一个Bug出现了,你也可以只需轻松的修改你的模板重新生成代码,然后在整个系统中这个Bug就会消失的无影无踪。这可比你以前使用的那种方式好的多:依靠你自己去查找因为这个Bug导致运行失败的场景中的所有实例。不推荐使用实际上功能及其强大的重构工具,它们可以帮助我们很多。但是,当它们遇到修改行为动作的情况时就显得非常有限,而这一点代码生成就非常适合。CodeSmith允许你定义包含丰富的元数据的属性来生成功能强大的模板集,更好的消息是它们看起来好运行起来都像Asp.net.你对丰富的元数据的选择报告RDBMS,XML,.net Types,甚至可以构造你自己的元数据。
.netTiers入门
.netTiers是用C#语言写的一套开源CodeSmith模板库。这套模板的主要目的是帮助开发人员避免简单重复的代码编写工作,同时,可以提供一个功能齐全的框架。使用这个框架,开发人员就可以把注意力集中到诸如UI层,业务规则,工作流,程序性能等关乎他们的程序更紧要的内容上来。应当把.netTiers看做一个关注你的领域模型的应用模块,以后会更加注重横向挖掘而不是纵向发展。也就是说,在未来的版本中.netTiers会把焦点集中到提供更多可以帮助您完成每天工作任务的内容上去。
.netTiers可以在领域驱动设计(MDD)的基础上为现有的数据库非常有效的生成一套相互关联的领域对象。本质上,MDD是这样的概念:预先设计好用来生成你程序的模型,MDD是因为许多UMl工具,比如Rational Rose等等而变得出名的。然而,正是伴随着CodeSmith的可以通过架构搜索器(SchemaExplorer)查找到丰富的元数据,.netTiers 使用大家非常熟悉的数据模型使得MDD的实现变得异常简单。(翻译的不好:However, with the advent of CodeSmith's rich set meta-data via it's SchemaExplorer, MDD has been particularly easy to adopt for .netTiers through the familiar data model.)那么,.netTiers的职责就是有能力去作一个合理的数据库设计,并为您的数据库生成一个很棒的领域模型。因为业务应用的主体是围绕数据进行的,.netTiers提供了让你尽可能容易的处理你的数据的能力。
当前版本特征
以下是.netTiers提供的汇总特征列表,你可以通过这份文档得到这些话题的更多信息。
- 为你的程序生成一个完全可编译的解决方案,其中包括独立的项目和框架层次。你可以在代码生成后立即开始你的程序开发。
- 生成全套的针对你的领域的存储过程。这些代码可以以内联形式的运行,就如同参数化的SQL一样,不是一定要当做存储过程使用。
- 针对你的数据库中的表,自动生成包括实体对象和它们的关系对象的领域模型。
- 高级实体检验规则引擎,可以使用任意的已生成的规则或用户委托的规则。
- 你可以使用所有部分类和所有具体类写自定义逻辑,这些代码在重新代码生成时不会被覆盖。
- 使用自定义的泛型集合类,该类实现了.NET ComponentModel等接口,并且可绑定,排序,筛选。
- 生成一个完整的网站项目,已经提前配置,可以立即操作你的数据。
- 生成一套完整的可执行网页控件,对于数据库可作为基础的功能网页可执行控制台。
- 生成一套完整的强类型化数据源控件为你的全部应用程序接口提供设计时支持,它们与对象数据源(ObjectDataSource)非常相似,只是更加具体,对开发人员更加友好。
- 为你的领域生成完成的WebService应用程序接口,可以很好的应用于WinForms软件或智能客户端应用程序,并且很容易配置。
- 为数据提供者生成一套完成的单元测试项目,大约可以覆盖50%。这些测试使用NUnit或者VSTS。
- 代码进行了完整的注释,可以应用到的你的文档中。这些注释完全符合微软的命名指导方针。
- 所有代码都放在了项目中的特定文件夹中,默认为自动包含到生成项目中的App_Code文件夹。
- 数据访问层接口包含如下查询支持:主键,外键,索引,多对多关系,全部,筛选的分页查询,和查找(Find),同时对数据库还包括新增,更新,删除操作。
- 你可以为你的实体写你自定义存储过程,.netTiers会对存储过程进行封装。这使你可以在.netTiers接口中包含自定义逻辑。
- 还有很多很多……坦率的说……
.netTiers 体系架构
上图中数据层(Data Tier)是由业务实体组件(数据本身)和数据访问逻辑组件(持久化逻辑)组成。
这个设计是依据微软的模式和实践指导方针: Designing Data Tier Components and Passing Data Through Tiers。
企业库应用模块
到目前或许你会说.nettiers不只是帮助你更加快速的进行数据访问,而是更加快速的处理应用中的方方面面。你也许听说过这样一句谚语或者忠告:更加灵活而不是努力的工作。.nettiers在设计这种解决方案的时候遵循的正是这样一条原则。能够使用给我们带来最佳实践和遵循微软模式和实践小组的知道方针的现有工具真是太棒了。.netTiers是建立在企业库之上的,而企业库本身就是提供许多应用程序共通需求的插件式的基于提供者模式的令人敬畏的框架。这些应用模块包括数据访问,日志,异常处理,应用健康度量,缓存,安全,加密等等!!!也就是说,你可以使用这些功能而不需要自己去写或这花钱去买这些组件,你只是拿来就是以了。你可以找到大量的相关资料,还有后面提供的使用入门链接。
Enterprise Library Developer Site (注:原文提供的链接已经不存在了,这是我自己找到的微软MSDN上的链接)
NUnit 和 VSTS
离开了单元测试的应用程序会怎么样呢?单元测试已经成为今天应用程序的整体中的一个方面,因为单元测试可以让开发人员继续前行。向你的应用中添加一项功能却会破坏你20年前编写的网站中的10个地方,甚至你没有编写,不了解这项新功能是如何工作的,没有什么会比这更糟糕的了。单元测试可以让你写一小端测试代码来覆盖测试你的方法和大块代码的正确性。你可以去模拟你的应用程序所支持的所有可能的场景,甚至故意去作一些手脚来观察你的应用程序会不会正确的做出响应。单元测试如此受欢迎的另外一个原因就是可以提供深入洞察API所支持的行为。你可以了解如何去扩展现有的API,如何与为你的领域生成的实体类进行交互。.netTiers为你的数据API提供了单元测试,它们会在你进行定制化你的数据API和你想去确认这样做不会破坏现有的其他代码的时候派上用场。现在有许许多多单元测试的工具包,单我们提供对两种最有影响的工具包的支持:NUnit和Visual Studio Team System .如果你打算使用NUnit,我们强烈建议你去下载TestDriven.net,它可以让你在Visual Studio环境中更简单的进行测试。
1 [Test]
2 public void Step_01_Insert()
3
{
4 // Establish additional pre-conditions here
5
6 Step_01_Insert_Generated();
7
8 // Add additional verification here
9 }
10 /**//// <summary>
11 /// Inserts a mock Categories entity into the database.
12 /// </summary>
13 private void Step_01_Insert_Generated()
14
{
15 using (TransactionManager tm = CreateTransaction())
16
{
17 mock = CreateMockInstance(tm);
18 Assert.IsTrue(DataRepository.CategoriesProvider.Insert(tm, mock), "Insert failed");
19
20 System.Console.WriteLine("DataRepository.CategoriesProvider.Insert(mock):");
21 System.Console.WriteLine(mock);
22
23
26 }
27 }
28
方案规划
在上篇文档中,你已经浏览了整个生成的所有项目,看到它们被分到几个不同的项目中。如果你不太了解多层设计的话,刚好这个可以首先作为一个范例。如果你不理解为什么我们生成松散的多个层,我会带你去用一会时间去探讨和阅读一些设计思想。请阅读初级读本Designing Data Tier Components and Passing Data Through Tiers白皮书,会让你了解多层架构是如何进行工作的。
为什么意味着松耦合?
松耦合的架构是一种开放的架构,架构中要尽量多的内部交互,同时从其它层中获取尽量少的信息。比如说,数据访问层是一个抽象的层次,它只知道数据访问API的方法,它根本不了解具体的数据库知识或者Web服务知识。在使用表Orders的API的时候,你确定使用的抽象提供者了解Orders提供者(OrdersProvider)的API,比如GetByOrderId(), Insert(), Update(), Delete(). 但是在这些方法中你无法找到任何sql语句或者任何命令去操作数据库。本质上,这一层只是定义了一种契约,要求任何的提供者必需实现这种契约才能成功的跟其它的提供者进行交互。这样做对在数据提供者之间的切换也非常有用,比如从SQL Server 提供者切换到Web服务提供者,或者相反。
好像有了更多的代码和工作,为什么这样做会有用呢?
事实上是有几个因素导致了技术在不段的变化。例如,通常商业就是买或卖,而现在新公司做事情总是喜欢使用最新的技术,试图去减小使用企业库进行数据访问的费用。他们试图去使用.NET Framework 3.0中的 DLinq ,微软下一代的数据访问技术。你可以非常轻松的创建一个DLinq提供者进行正确的加载,并且你的API还在实际运行当中,代码的破坏在各层间传递的危害是最小的。
整体上,工程的分成如下所示(使用Northwind作为例子):
.netTiersAPI层次
- Northwind.Entities - 实体层是根据表模式,数据传输对象和域模型进行设计的。 这一层目的是在持久化状态和数据完整性的时候进行在层间传递数据。 定制化会包括一些基本的业务规则,比如:范围检测,类型监测,长度,格式化;像展示的名字会连接两个属性,比如对一个用户类会有 FirstName + " " + LastName 。
- Northwind.Data - 数据的抽象层调用全局唯一的Datarepository去访问生成的API.这是访问你的数据的入口点,并且知道你的API支持的数据类型。但是它不了解提供者的具体实现。
- Northwind.Data.SqlClient - 针对微软Sql Server 操作的提供者。
- Northwind.Data.WebServiceClient - Web 服务的提供者,作为一个客户端可以调用下边介绍的Web服务的EndPoint。这样可以让你很轻松的通过一个远程客户端使用.netTiers,比如只能客户端。
- Northwind.Services or Northwind.Domain - 这一层提供了你的复杂业务逻辑规则的应用边界和数据API.这里的选择是使用ServiceLayer模式或者使用DomainModel 模式。在这一层里 你可以定义所有的复查行为,但是你并不希望实现所有的行为。这一层里包括处理器(Processors) ,你可以用来分类定义好的行为实现。
- Northwind.WebServices - 断开式的Web服务项目提供了一个可以使用的暴露了数据API的Web服务EndPoint。这实际上既是一个提供者,又是一个使用者。因为它会被Web服务的客户端层调用,又会在架构的服务器端去使用Sql Client 。
.netTiers API 的使用者
- Northwind.UnitTests - 单元测试使用API并且为数据访问API提供单元界别的测试。
- Northwind.Web - 这一层提供了一套可以使用的ASP.net控件集与在进行web应用程序开发的时候协助你更有效进行数据访问帮助类集。
- Northwind.Website - 如果你选择了这项,这是一个入门的网站。会为你自动生成一个网站项目,项目中包括正确的引用,在生成以后你可以立即使用这个网站进行操作。
.netTiers模式
.netTiers小组付出了巨大的努力在进行应用开发时使用最佳实践。我们遵循微软给出的如何以最佳的方式使用他们的平台的知道方针,其中包括了微软模式与实践小组类库的很多的使用。
下面就是在.netTiers 2 中使用的模式的主要资料。
主要都集中在下面这些优秀的开发人员的资源上面:
patternshare.org | dofactory.com | DavidHayden.com
服务层
http://martinfowler.com/eaaCatalog/serviceLayer.html
Processors
By default is a Pipeline:
http://www.enterpriseintegrationpatterns.com/PipesAndFilters.html
but easily can be used with workflow management in:
http://www.enterpriseintegrationpatterns.com/ProcessManager.html
Each Individual Processor uses a:
Command
http://www.dofactory.com/Patterns/PatternCommand.aspx
Flexible enough to be used within a strategy passed into the ctor to manage different behaviors in complex logic. http://www.dofactory.com/Patterns/PatternStrategy.aspx
DomainModel + ActiveRecord
http://martinfowler.com/eaaCatalog/domainModel.html
http://martinfowler.com/eaaCatalog/activeRecord.html
数据访问层
Singleton, Decorator
http://msdn2.microsoft.com/en-us/library/ms998426.aspx
http://www.dofactory.com/Patterns/PatternDecorator.aspx
Data Transfer Objects:
http://martinfowler.com/eaaCatalog/dataTransferObject.html
Repository Provider:
http://davidhayden.com/blog/dave/archive/2004/05/19/259.aspx
实体层
Each Entity - Memento, State, DomainModel, TableModule
http://www.dofactory.com/Patterns/PatternMemento.aspx
http://www.dofactory.com/Patterns/PatternState.aspx#_self2
http://martinfowler.com/eaaCatalog/domainModel.html
http://martinfowler.com/eaaCatalog/tableModule.html
Entity Factory
http://www.dofactory.com/Patterns/PatternFactory.aspx
WebService Client - Proxy
http://www.dofactory.com/Patterns/PatternProxy.aspx
Sql Expression - Builder
http://www.dofactory.com/Patterns/PatternBuilder.aspx
(注:最后的资源索引就没有进行翻译,原文链接。下一篇:入门)