另外我写这篇文章时是一边看源码一边写,所以建意大家最好安装一个Petshop3,因为时间仓促,水平有限,如我有不对之处请给我发Email更正。email:cocoboy79@163.com qq:364941
首先我们来看一下DAL层。
一:Data Access Layer:
1 PetShop.Utility如下图:(上表中Utility为其实现工程)
<shape id="_x0000_i1027" style="WIDTH: 140.25pt; HEIGHT: 1in" type="#_x0000_t75" o:ole=""><img alt="" o:title="" src="http://www.csdn.net/Develop/ArticleImages/21/21158/CSDN_Dev_Image_2003-9-20008532.png"></shape>
正如上表所描述,这个名字空间有两个类一个是ConnectionInfo用于加密解密数据库连接信息,另一个DataProtector调用了Crypt32.dll和kernel32.dll实现一些底层数据安全操作,这个类要在下面的PetShop.XXXDAL名字空间中调用,可见Petshop.Utility只是起到的是数据访问辅助工具的作用。
2 PetShop.SQLServerDAL ――系统结构图中DAL层中的SqlServer DAL子层实现
<shape id="_x0000_i1028" style="WIDTH: 119.25pt; HEIGHT: 117.75pt" type="#_x0000_t75" o:ole=""><img alt="" o:title="" src="http://www.csdn.net/Develop/ArticleImages/21/21158/CSDN_Dev_Image_2003-9-20008534.png"></shape>
SqlHelper类实际上是封装了关于此系统中数据库操作访问的一些常用功能,其中它还会调用上面的PetShop.Utility中的ConectionInfo类方法加密解密连接字符串,如:ConnectionInfo.DecryptDBConnectionString方法。SqlHelper类是基于Microsoft Data Access Application Block for .NET。这个东西是用来帮助用户更好的在.NET的访问数据。如MS一段话:Are you involved in the design and development of data access code for .NET-based applications? Have you ever felt that you write the same data access code again and again? Have you wrapped data access code in helper functions that let you call a stored procedure in one line? If so, the Microsoft® Data Access Application Block for .NET is for you。其实可以自已写一个类似SqlHelper的东西,以实现一般化的对数据库的操作,以在各项目中重用,当然也可以使用现在的MS为你做好的这个SqlHelper或是Microsoft® Data Access Application Block for .NET,避免不同项目中总是写同样的重复的数据库访问程序。有时间最好还是看一下SqlHelper的具体程序实现思路以及所提到的那个Microsoft Data Access Application Block for .NET。不过这里我们的SqlHelper应该只是部分实现。更全面信息请参看:http://msdn.microsoft.com/library/en-us/dnbda/html/daab-rm.asp
Account类对用户帐户进行操作如Insert,Update,SignIn,其中这些对数据库的操作,使用了上面的SqlHelper类来实现。另外Inventory和Order,Product,Profile和Account类的都是同样对数据库相关表进行操作,程序风格一致,这些类中对数据库的操作都是通过此名字空间下的SqlHelper类进行的,例如,下面语句:
private const string SQL_INSERT_SIGNON = "INSERT INTO SignOn VALUES (@UserId, @Password)";
private const string PARM_USER_ID = "@UserId";
private const string PARM_PASSWORD = "@Password";
来定义一个sql语句,以及声明其中可变参数,然后像下面这样用SqlHelper类的合适的方法执行:
SQLHelper.ExecuteNonQuery(trans, CommandType.Text, SQL_INSERT_SIGNON, signOnParms);
最后在SQLHelper.ExecuteNonQuery实现中,再调用ado.net中的相关类最终执行对数据库的操作,可见SqlHelper在这里又封装了一下ado.net相关类以优化数据操作。正如SqlHelper.cs中注释提示:The SqlHelper class is intended to encapsulate high performance, scalable best practices for common uses of SqlClient.下面是SqlHelper. ExecuteNonQuery的实现内容:
public static int ExecuteNonQuery(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) {
//注:运行时cmdText的实参就是SQL_INSERT_SIGNON
SqlCommand cmd = new SqlCommand();
using (SqlConnection conn = new SqlConnection(connString)) {
PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
}
另外Inventory和Order,Product,Profile和Account类的声明都是像public class Account : IAccount这样实现某个相关的接口,像IAccount这样的接口是在PetShop.IDAL中声明的,见后面介绍。
3 PetShop.OracleDAL ―――系统结构图中 DAL层的OracleDAL子层实现
<shape id="_x0000_i1029" style="WIDTH: 129pt; HEIGHT: 121.5pt" type="#_x0000_t75" o:ole=""><img alt="" o:title="" src="http://www.csdn.net/Develop/ArticleImages/21/21158/CSDN_Dev_Image_2003-9-20008536.png"></shape>
个人认为结构应该同上面的PetShop. SQLServerDAL,另外SqlHelper变成了OraHelper,在OraHelper中当然具体实现了对特定的Oracle数据库的联接操作,看一下源程序很明显原来的 SqlCommand cmd = new SqlCommand(); 变成了OracleCommand cmd = new OracleCommand();。
注意一下:在系统结构图中的DAL层还有两个XXX DAAB的子层,它们对应的实现在哪里呢? 下面对应一下:
以下是左边是图中 DataAccessLayer的各部分,右边是具体实现所在名字空间或类
SqlServer DAL――PetShop.SQLServerDAL名字空间
Sql DAAB――PetShop.SqlServerDal.SqlHelper类
Oracle DAL――PetShop.OracleDAL名字空间
Oracle DAAB――PetShop.OracleDAL.OraHelper类
4 PetShop.IDAL 数据访问接口――对应系统结构图中DAL Interface
<shape id="_x0000_i1030" style="WIDTH: 122.25pt; HEIGHT: 110.25pt" type="#_x0000_t75" o:ole=""><img alt="" o:title="" src="http://www.csdn.net/Develop/ArticleImages/21/21158/CSDN_Dev_Image_2003-9-20008538.png"></shape>
接口是一种系列‘功能’的声明或名单,接口没有实现细节,如下接口IAccount定义也可以看出IAccount只有声明:
using System;
using PetShop.Model;
namespace PetShop.IDAL
{
// Inteface for the Account DAL
public interface IAccount
{
// Authenticate a user
AccountInfo SignIn(string userId, string password);
/// Get a user's address stored in the database
AddressInfo GetAddress(string userId);
/// Insert an account into the database
void Insert(AccountInfo account);
/// Update an account in the database
void Update(AccountInfo Account);
}
}
您只需要调用接口,而不用管接口是如何实现的那么接口没有实现,调用它有什么用?实际上接口的实现是由某个类来做的,那么这里的IAccount接口是由PetShop.SqlServerDAL.Account类或是PetShop.OracleDAL.Account类来实现的,从他们的定义可以看到:
public class Account : IAccount {…….}
为什么是两个类都实现同一接口又是‘或’呢?因为这里使用接口的目的就是为了统一‘外观’,当上层BLL层调用此接口方法时不用知道这个接口由哪个类实现的。那谁来确定使用哪个类的实现?请再看下面。
(PetShop.IDAL下的其它接口和IAccount一样,故在此略过。)
5 PetShop.DALFactory 数据访问工厂
<shape id="_x0000_i1026" style="WIDTH: 120pt; HEIGHT: 107.25pt" type="#_x0000_t75" o:ole=""><img alt="" o:title="" src="http://www.csdn.net/Develop/ArticleImages/21/21158/CSDN_Dev_Image_2003-9-200085310.png"></shape>
工厂模式是设计模式的一种,以我理解就像Factory这个词一样,对于用户来说,工厂里产品如何生产的你不用知道,你只要去用工厂里生产出来的东西就可以了。MSPetShop3.0用工厂模式来实现了对SqlServer和Oracle数据库访问的操作,而用户(business Logic Layer)不用知道也不用关心后台用的是哪一种数据库,它只要用接口就行了,接口中定义了要用的方法,当调用接口时会根据具体的情况再去调用底层数据访问操作。而现在这个DALFactory就是关键,当BLL层要操作数据库时,DALFactory会根据具体情况再去使用本文上面介绍的SqlServerDAL和OracleDAL中的一个。这样系统上层只管调用,而下层来实现细节,上级只管发号施令,下级去干活。对于上层来说实现细节被隐藏了。
那么DALFactory是如何决定应该用SqlServerDAL还是用OracleDAL的呢?我们接着分析。
以下是PetShop.DALFactory.Account类的实现:
namespace PetShop.DALFactory {
/// <summary>
/// Factory implementaion for the Account DAL object
/// </summary>
public class Account
{
public static PetShop.IDAL.IAccount Create() //<<<<ß----这里返回接口
{
/// Look up the DAL implementation we should be using
string path = System.Configuration.ConfigurationSettings.AppSettings["WebDAL"];
string className = path + ".Account";
// Using the evidence given in the config file load the appropriate assembly and class
return (PetShop.IDAL.IAccount) Assembly.Load(path).CreateInstance(className);
}
}
}
以下则是web.config中<appSettings>节点中的一部分:
<add key="WebDAL" value="PetShop.SQLServerDAL" />
<add key="OrdersDAL" value="PetShop.SQLServerDAL" />
<add key="Event Log Source" value=".NET Pet Shop" />
上面的Create()方法返回IAccount接口,用System.Configuration.ConfigurationSettings.AppSettings["WebDAL"];则可以得到Web.config的<appsettings>节点中的关于系统中应该使用哪个数据访问层(SqlserverDAL还是OracleDAL)的信息。因为我在安装PetShop3.0时选择的是Sqlserver所以在此是:value="PetShop.SQLServerDAL",如果用的是Oracle那就是value="PetShop.OracleDAL" 了吧!而且这个文件也应该是可以更改的。接下来className=path+”.Account”返回的应该是PetShop.SQLServerDAL.Account,然后再用Assembly.Load加载PetShop.SQLServerDAL.dll,同时创建PetShop.SQLServerDAL.Account的实例,并以接口(PetShop.IDAL.IAccount)类型返回。这样BLL调用IAccount接口时就会用PetShop.SQLServerDAL.Account类的实现代码。(回上面第4再看一下)
看!这样根据系统当前Web.config文件的配置描述(这也应该是系统运行时实际的配置),BLL层只要像下面这样:
// Get an instance of the account DAL using the DALFactory
IAccount dal = PetShop.DALFactory.Account.Create();
AccountInfo account = dal.SignIn(userId, password);//<<ß----看看上面第4点的IAccount接口
就可以直接调用接口方法通过下层DAL层操作数据库了(在此具体为用户账号相关操作),而BLL层并不用知道应该通过SqlserverDAL还是OracleDAL访问数据库,这由都DAL Factory决定,你用的是什么数据库以及底层细节,更不用BLL知道,这样做的好处是对于BLL层以及更上层的程序不会或很少机率会因为底层程序变动影响,因为BLL层中调用接口就行了,只要那个接口定义没变,一切仍然OK.
6 PetShop.ConfigTool
<shape id="_x0000_i1031" style="WIDTH: 167.25pt; HEIGHT: 1in" type="#_x0000_t75" o:ole=""><img alt="" o:title="" src="http://www.csdn.net/Develop/ArticleImages/21/21158/CSDN_Dev_Image_2003-9-200085312.png"></shape>
首先在..\Microsoft\PetShop\ConfigTool\中有一个app.config文件,看一下其中内容,分别定义了两种数据库的联接字符串,在app.config中有一行 <add key="WebConfigFileLocation" value="Web\Web.config" /> 则标识出给asp.net程序使用的web.config配置文件的相对位置。然后看一下PetShopConnectionString的EncryptConnectionString方法的源码,这个类中先是从当前目录的app.config文件中读出web.config文件的位置,如下:
public static readonly string CONFIGFILE = ConfigurationSettings.AppSettings["WebConfigFileLocation"];
然后语句
XmlDocument doc = new XmlDocument();
doc.Load(CONFIGFILE);
加载Web.config文件,最后将加密的连接字符串写入Web.config对应的XML节点中。以供Asp.net应用程序使用。其中的加密还是使用PetShop.Utility。
而ConfigConsole,调用PetShopConnectionString类EncryptConnectionString执行对联接字符串进行加密。另外PetShopEventLog类也是在ConfigConsole中使用的。用于记录程序日志。
所以在最后部署时Web.config的连接字符串是加密的。
7 PetShop.Model 业务实体模型
<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype>
http://www.surfsky.com/bbs/myfiles/7.bmp
这个本来想在分析BLL层时再说,但是在SqlServerDAL和OracleDAL中都使用了这些Model,无论怎么样,上层的程序执行最终结果都是要操作数据库,而数据库是关系型,不是面向对象的,那就得把平面的‘表’结合业务规则抽象成类,这样想办法让上层(BLL及以上)以为自已在操作类而不是数据库表,从而使‘它们’感觉没有数据库的存在,上层只管面向对象编程就可以了。类似现在所说的O-R MAPPING,但O-R MAPPING比这种简单的数据到对象的持久化要复杂。据说可以在表结构有变化的情况下,上层应用程序代码不用更改,只要改O-R MAPPING的相关设置就可以了。
上面第2节中已看到Petshop的SqlServerDal和OracleDal中定义的sql语句,然后根据上层的调用,把sql语句传给SqlHelper执行,再来看看SqlServerDal的一段程序:
private void SetAccountParameters(SqlParameter[] parms, AccountInfo acc) {
parms[0].Value = acc.Email;
parms[1].Value = acc.Address.FirstName;
parms[2].Value = acc.Address.LastName;
parms[3].Value = acc.Address.Address1;
parms[4].Value = acc.Address.Address2;
parms[5].Value = acc.Address.City;
parms[6].Value = acc.Address.State;
parms[7].Value = acc.Address.Zip;
parms[8].Value = acc.Address.Country;
parms[9].Value = acc.Address.Phone;
parms[10].Value = acc.UserId;
}
parms[x]就是那些有声明为常量的有参数的Sql语句中的参数,这里用Model中的AccountInfo的各Field和这些参数Mapping。所以对于BLL层,只知道这些Model就可以了,反正最后在SqlServerDAL或是OracleDAL中Model的成员们会Mapping到参数中以存取数据库(为什么不直接Mapping到数据集的字段呢?我想应该是因为这里数据库操作直接给SqlHeper的原因,不然就没必要用SqlHelper了。于是才又多了图中的xxx DAAB层,这样Mapping给参数再传给DAAB来处理)
Data Access Layer总结:
DAL完成数据库访问任务,上层(BLL)直需调用接口即可,不用知道具体访问细节,用Factory模式来实现,使用运行时读取web.config的方法来得到连接配置信息,最后选用SqlServerDAL或OracleDAL之一的相对具体子层,同时使用SqlHelper或OraHelper之一来完成数据库操作。
相关推荐
4. **三层架构**:PetShop 3.0采用了业务逻辑层(Business Logic Layer, BLL)、数据访问层(Data Access Layer, DAL)和表示层(Presentation Layer)的三层架构设计,这种设计模式有利于代码的重用和模块化,是Web...
1. **分层架构**:PetShop3.0采用了常见的三层架构,包括表现层(Presentation Layer)、业务逻辑层(Business Logic Layer, BLL)和数据访问层(Data Access Layer, DAL)。这种架构有助于代码的组织和维护,提高了...
它使用了三层架构,即表示层、业务逻辑层和数据访问层,为开发者提供了理解Web应用程序架构的良好起点。 2. PetShop 3.0:随着.NET Framework 2.0的发布,PetShop 3.0引入了ASP.NET 2.0的新特性,如母版页、主题、...
《.Net PetShop 4.0:微软分层架构的典范》 .Net PetShop 4.0 是微软推出的一个开源示例项目,旨在演示如何利用 .NET Framework 构建一个完整的、分层的企业级应用程序。这个项目对于初学者,尤其是那些在IT行业中...
此外,还引入了ADO.NET进行数据库操作,展示了如何构建三层架构的应用程序。 2. PetShop 3.0: 随着ASP.NET 2.0的发布,PetShop 3.0引入了更多的改进和新特性。这一版加强了数据访问层,使用了Entity Framework的...
7. **经典三层结构**:经典的三层架构通常包括表示层(UI)、业务逻辑层( BLL )和数据访问层(DAL)。表示层负责用户交互,业务逻辑层处理业务规则,数据访问层则负责与数据库的交互。 8. **微软Duwamish7**:...
PetShop在后续版本中对此进行了优化,例如PetShop2.0没有严格区分数据访问层,导致职责混乱,而PetShop3.0和4.0则重新明确了分层,引入了缓存和异步处理以改善性能。 在.NET中的标准BS(Browser-Server)分层结构中...
这种架构通常包括三个主要部分:表现层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。表现层负责与用户交互,处理用户请求并显示结果。业务逻辑层处理应用程序的...
Petshop4.0采用了典型的三层架构模式:数据访问层、业务逻辑层(或称领域层)以及表示层。每一层都有其特定的功能和职责范围,这种分层架构能够帮助开发者更好地组织代码,确保各部分之间的松散耦合,从而提高系统的...
PetShop 2.0的架构并不完全遵循这个标准,其数据访问层并不明显,可能更倾向于混合式设计。 随着PetShop版本的迭代,架构的演变反映了设计原则的优化和调整。理解这些变化可以帮助我们更好地适应技术发展,提升软件...
在 PetShop 的架构中,主要分为三层:数据访问层、业务逻辑层和表示层。 **数据访问层**(DAL,Data Access Layer)是系统的基础,负责与数据库的交互。它实现了对数据表的基本 CRUD 操作(Create、Read、Update、...
在【系统架构设计】方面,PetShop采用的是典型的"三层"架构,这包括数据访问层(DAL)、业务逻辑层(BLL,也称为领域层)和表示层。这种分层设计有几个关键优点: 1. **结构清晰**:将系统功能划分为不同的层,使得...
PetShop的演变历程显示了架构的改进,如PetShop 2.0的非典型三层结构,以及PetShop 3.0和4.0引入了更清晰的数据访问层和优化性能的策略,如缓存和异步处理。 在PetShop 4.0中,`DAL Interface`抽象了数据访问逻辑,...
PetShop是一个范例,微软用它来展示.Net企业系统开发的能力。 在软件体系架构设计中,分层式结构是最常见,...微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或成为领域层)、表示层.
Petshop4的架构设计细致周全,涵盖了表现层、模型层、业务逻辑层和数据访问层等多个层面,形成了一个完整而复杂的项目体系。其中,各个项目模块紧密相连,共同构建出一个高效稳定的企业级应用。 1. **WEB**:表示层...
2.0版本的体系结构采用了传统的三层架构,包括表示层(Web UI)、业务逻辑层(BLL)和数据访问层(DAL)。每个层都负责特定的任务,如UI处理用户交互,BLL执行业务规则,而DAL处理数据操作。 6. **.NET Pet Shop ...
Entity Framework提供了概念模型,可以映射到数据库模式,简化了数据访问层的编写,降低了数据库依赖,提升了代码的可维护性。 四、ASP.NET MVC 虽然Pet Shop 5.0的具体实现没有明确指出是否使用了ASP.NET MVC,但...
学生可以访问多个官方和第三方网站获取相关资料和示例代码,如Microsoft的官方网站(gotdotnet.com、msdn.microsoft.com)、ASP.NET官方社区(asp.net)以及各种示例项目,例如Duwamish 7.0(网上图书销售)、Fitch ...
开发语言采用ASP.NET,编程语言为C#,数据访问层使用ADO.NET,同时利用Web窗体、Web服务、服务器控件、用户控件和自定义控件构建UI。CSS用于样式控制,物理工程分层设计增强了代码组织,数据库迁移和加密配置文件...