版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
基于.NET平臺(tái)的分層架構(gòu)實(shí)戰(zhàn)(完整資料)(可以直接使用,可編輯優(yōu)秀版資料,歡迎下載)
通過瀏覽博客園的文章發(fā)現(xiàn),很多朋友對(duì)分層架構(gòu)特別感興趣,剛好我剛做完的畢業(yè)設(shè)計(jì)就是專門研究.NET平臺(tái)上分層架構(gòu)的(題目叫“基于.NET平臺(tái)的分層架構(gòu)與設(shè)計(jì)模式應(yīng)用研究”).通過做這篇論文,我對(duì)分層架構(gòu)有了一定的了解,所以,就萌發(fā)了想寫一個(gè)文章系列,詳述一下分層架構(gòu)。然而,論文的理論性太強(qiáng),不適合在網(wǎng)上發(fā)布,尤其不適合初學(xué)者理解,所以,我想在這個(gè)文章系列中,少講理論,而是通過做一個(gè)完整的案例來討論分層架構(gòu)的基本方法,這樣會(huì)直觀很多。希望在這個(gè)文章系列的寫作過程中,能和朋友們一起學(xué)習(xí),一起進(jìn)步。
為了讓朋友們把主要精力放在理解分層架構(gòu)而不是案例本身,我準(zhǔn)備選擇一個(gè)相對(duì)簡(jiǎn)單的留言本系統(tǒng)作為Demo,這個(gè)系統(tǒng)的名字就叫做NGuestBook。
?
初步計(jì)劃將這個(gè)文章系列分為以下幾篇:
1.綜述?
2.系統(tǒng)需求分析及數(shù)據(jù)庫設(shè)計(jì)?
3.架構(gòu)概要設(shè)計(jì)
4.實(shí)體類的實(shí)現(xiàn)?
5。接口的設(shè)計(jì)與實(shí)現(xiàn)
6。依賴注入及IoC的設(shè)計(jì)與實(shí)現(xiàn)
7。數(shù)據(jù)訪問層的第一種實(shí)現(xiàn)——Access+動(dòng)態(tài)生成SQL語言?
8.數(shù)據(jù)訪問層的第二種實(shí)現(xiàn)——SQLServer+存儲(chǔ)過程?
9.數(shù)據(jù)訪問層的第三種實(shí)現(xiàn)——基于NBear框架的ORM實(shí)現(xiàn)?
10.業(yè)務(wù)邏輯層的實(shí)現(xiàn)
11。表示層的實(shí)現(xiàn)?
12。使用ASP.NETAJAX框架對(duì)表示層進(jìn)行改進(jìn)
13.總結(jié)
當(dāng)然,以上只是初步計(jì)劃,在寫文章的過程中可能會(huì)根據(jù)具體情況適當(dāng)調(diào)整,但是內(nèi)容大體就是這些。
這個(gè)文章系列不會(huì)對(duì)所用到的技術(shù)進(jìn)行詳細(xì)講解,具體請(qǐng)參考相關(guān)文獻(xiàn),閱讀文章前最好能對(duì)以下技術(shù)有一個(gè)了解:?
1.C#語言?
2。ASP.NET?
3.設(shè)計(jì)模式
4.關(guān)系數(shù)據(jù)庫基礎(chǔ)知識(shí)?
5.軟件架構(gòu)基本原則與軟件工程基礎(chǔ)知識(shí)?
6?;贜Bear框架的ORM技術(shù)
7。JavaScript,Ajax
8。ASP.NETAJAX框架(特別是客戶端編程)?
9.HTML,CSS,標(biāo)準(zhǔn)化布局??
另外,本文章系列是基于.NETframework2.0框架平臺(tái)進(jìn)行討論,3。5平臺(tái)的新特性(如LINQ、ASP.NETMVC等)不會(huì)討論,IDE使用VisualStudio2005,數(shù)據(jù)庫會(huì)用到SQLServer2005Express和Access2003。基于.NET平臺(tái)的分層架構(gòu)實(shí)戰(zhàn)(完整資料)(可以直接使用,可編輯優(yōu)秀版資料,歡迎下載)在實(shí)際的項(xiàng)目中,需求分析和數(shù)據(jù)庫的設(shè)計(jì)是很重要的一個(gè)環(huán)節(jié),這個(gè)環(huán)節(jié)會(huì)直接影響項(xiàng)目的開發(fā)過程和質(zhì)量。實(shí)際中,這個(gè)環(huán)節(jié)不但需要系統(tǒng)分析師、軟件工程師等計(jì)算機(jī)方面的專家,還需要相關(guān)領(lǐng)域的領(lǐng)域?qū)<覅⑴c才能完成。??
但是,在這個(gè)文章系列中,所要使用的Demo僅僅是一個(gè)例子,而且其業(yè)務(wù)極為簡(jiǎn)單,因此,這里并不是真正的需求分析和數(shù)據(jù)庫設(shè)計(jì),而是將Demo的需求和數(shù)據(jù)庫羅列至此,使朋友們對(duì)Demo有一個(gè)大體的了解,方便后續(xù)文章中開發(fā)過程的理解。
需求分析:
這個(gè)項(xiàng)目是一個(gè)留言本,其業(yè)務(wù)極為簡(jiǎn)單,現(xiàn)將其描述如下。
1.任何訪問者可以進(jìn)行留言,留言完成后,不會(huì)立即顯示正文,而是要經(jīng)過管理員驗(yàn)證后才可顯示。
2。任何訪問者可以對(duì)留言發(fā)表評(píng)論,未通過驗(yàn)證的留言不可以評(píng)論。?
3.管理員可以對(duì)留言進(jìn)行回復(fù)(這個(gè)回復(fù)不同于評(píng)論,是直接顯示在正文下面,而且是一個(gè)留言只能有一個(gè)回復(fù)),并可對(duì)留言與評(píng)論實(shí)行刪除,以及對(duì)留言進(jìn)行通過驗(yàn)證操作。?
4.管理員分為超級(jí)管理員和普通管理員。超級(jí)管理員只有一個(gè),負(fù)責(zé)對(duì)普通管理員實(shí)行添加、刪除操作.普通管理員可偶多個(gè),負(fù)責(zé)對(duì)留言的管理,并可以修改自己的登錄密碼.
?
這個(gè)項(xiàng)目的用例圖如下:?
數(shù)據(jù)庫設(shè)計(jì):?
設(shè)計(jì)數(shù)據(jù)表之前,首先進(jìn)行實(shí)體和關(guān)系的識(shí)別與確定。?
通過需求分析,可以觀察得出,本項(xiàng)目的實(shí)體有:管理員(不包括超級(jí)管理員),留言,評(píng)論。本項(xiàng)目的關(guān)系有:留言與評(píng)論間的一對(duì)多關(guān)系.??
進(jìn)一步,數(shù)據(jù)庫各表的設(shè)計(jì)如下:
?
管理員表(TAdmin)?
ID
int
管理員ID
NotNull
主鍵,自增
Name
varchar(20)
登錄名
NotNull
Password
varchar(50)
登錄密碼
NotNull
使用MD5加密??
留言表(TMessage)
ID
int
留言ID
NotNull
主鍵,自增
GuestName
varchar(20)
留言者用戶名
NotNull
GuestEmail
varchar(100)
留言者E-mail
Null
Content
text
留言內(nèi)容
NotNull?
Time
datetime
發(fā)表留言時(shí)間
NotNull
?
Reply
text
回復(fù)
Null
IsPass
varchar(10)
是否通過驗(yàn)證
NotNull
?
評(píng)論表(TComment)
Content
text
評(píng)論內(nèi)容
NotNull?
Time
datetime
發(fā)表評(píng)論時(shí)間
NotNull
MessageID
int
所屬留言的ID
外鍵基于。NET平臺(tái)的分層架構(gòu)實(shí)戰(zhàn)(三)—架構(gòu)概要設(shè)計(jì)
本文主要是對(duì)將要實(shí)現(xiàn)的架構(gòu)進(jìn)行一個(gè)總體的描述,使朋友們對(duì)這個(gè)架構(gòu)有個(gè)宏觀上的認(rèn)識(shí)。這篇文章理論性的東西會(huì)偏多一點(diǎn),從下篇開始,將進(jìn)行實(shí)際項(xiàng)目的開發(fā).這篇文章的許多內(nèi)容摘自我的畢業(yè)論文.架構(gòu)基本原則:這里,將描述一些在這個(gè)架構(gòu)設(shè)計(jì)中的基本原則,其中很多都是經(jīng)典的設(shè)計(jì)原則,不過針對(duì)分層架構(gòu)的特點(diǎn),用我自己的語言進(jìn)行了描述。其中也有我自己提出的原則。逐層調(diào)用原則及單向調(diào)用原則現(xiàn)在約定將N層架構(gòu)的各層依次編號(hào)為1、2、…、K、…、N-1、N,其中層的編號(hào)越大,則越處在上層.那么,我們?cè)O(shè)計(jì)的架構(gòu)應(yīng)該滿足以下兩個(gè)原則:1.第K(12.如果P層依賴Q層,則P的編號(hào)一定大于Q。其中第一個(gè)原則,保證了依賴的逐層性,及整個(gè)架構(gòu)的依賴是逐層向下的,而不能跨層依賴。第二個(gè)原則,則保證了依賴的單向性,及只能上層依賴底層,而不能底層反過來依賴上層。針對(duì)接口編程,而不是針對(duì)實(shí)現(xiàn)編程
這里所指的接口,不是特指編程語言中的具體語言元素(如C#中由Interface定義的語言接口),而是指一種抽象的,在語義層面上起著接合作用語義體。它的具體實(shí)現(xiàn),可能是接口,可能是抽象類,甚至可能是具體類。我認(rèn)為,從不同的視角,接口可以有以下兩種定義:1.接口是一組規(guī)則的集合,它規(guī)定了實(shí)現(xiàn)本接口的類或接口必須擁有的一組規(guī)則。體現(xiàn)了自然界“如果你是……則必須能……”的理念。2。接口是在一定粒度視圖上同類事物的抽象表示。注意這里我強(qiáng)調(diào)了在一定粒度視圖上,因?yàn)椤巴愂挛铩边@個(gè)概念是相對(duì)的,它因?yàn)榱6纫晥D不同而不同。具體到N層架構(gòu)中,針對(duì)接口編程的意義在部分上是這樣的:?現(xiàn)仍約定將N層架構(gòu)的各層依次編號(hào)為1、2、…、K、…、N-1、N,其中層的編號(hào)越大,則越處在上層,那么第K層不應(yīng)該依賴具體一個(gè)K-1層,而應(yīng)該依賴一個(gè)K-1層的接口,即在第K層中不應(yīng)該有K—1層中的某個(gè)具體類.依賴倒置原則在軟件設(shè)計(jì)原則中,有一種重要的思想叫做依賴倒置。它的核心思想是:不能讓高層組件依賴底層組件,而且,不管高層組件和底層組件,兩者都應(yīng)依賴于抽象。那么,這個(gè)原則和我們上面的原則是否矛盾呢?其實(shí)并不矛盾。因?yàn)檫@個(gè)原則定義中的“依賴”是指“具體依賴",而上面定義中的依賴全部指“抽象依賴”。我對(duì)這兩種依賴的定義如下:具體依賴——如果P層中有一個(gè)或一個(gè)以上的地方實(shí)例化了Q層中某個(gè)具體類,則說P層具體依賴于Q層。抽象依賴—-如果P層沒有實(shí)例化Q層中的具體類,而是在一個(gè)或一個(gè)以上的地方實(shí)例化了Q層中某個(gè)接口,則說P層抽象依賴于Q層,也叫接口依賴于Q層。從這兩個(gè)定義可以看到,所謂的依賴倒置原則,正是上面提到針對(duì)接口編程,而不是針對(duì)實(shí)現(xiàn)編程,兩者在本質(zhì)上是統(tǒng)一的.綜上所述,可以看出,本課題設(shè)計(jì)的分層架構(gòu),應(yīng)該是這樣一種架構(gòu):?1。N層架構(gòu)的各層依次編號(hào)為1、2、…、K、…、N—1、N,其中層的編號(hào)越大,則越處在上層。2.架構(gòu)中僅存在一種依賴,即第K層接口依賴第K—1層,其中1封裝變化原則封裝變化的原則定義為:找出應(yīng)用中可能需要變化之處,把它們獨(dú)立出來,不要和那些不需要變化的代碼混雜在一起。開放-關(guān)閉原則開發(fā)-關(guān)閉原則定義為:對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉.具體到N層架構(gòu)中,可以描述為:當(dāng)某一層有了一個(gè)新的具體實(shí)現(xiàn)時(shí),它應(yīng)該可以在不修改其他層的情況下,與此新實(shí)現(xiàn)無縫連接,順利交互。單一歸屬原則在這個(gè)架構(gòu)中,任何一個(gè)操作類都應(yīng)該有單一的職責(zé),屬于單獨(dú)的一層,而不能同時(shí)擔(dān)負(fù)兩種職責(zé)或?qū)儆诙鄠€(gè)層次(實(shí)體類及輔助類可以被多個(gè)層使用,但它們不屬于任何一個(gè)層,而是獨(dú)立存在)。層次劃分:目前,典型的分層架構(gòu)是三層架構(gòu),即自底向上依次是數(shù)據(jù)訪問層、業(yè)務(wù)邏輯層和表示層.這種經(jīng)典架構(gòu)經(jīng)歷了時(shí)間的考驗(yàn)和實(shí)踐的多次檢驗(yàn),被認(rèn)為是合理、有效的分層設(shè)計(jì),所以,在本文中,將沿襲這種經(jīng)典架構(gòu),使用數(shù)據(jù)訪問層、業(yè)務(wù)邏輯層和表示層的三層架構(gòu)體系.職責(zé)劃分:
目前,在典型的三層架構(gòu)中,對(duì)層次各自的職責(zé)劃分并沒有一個(gè)統(tǒng)一的規(guī)范,綜合現(xiàn)有的成功實(shí)踐和.NET平臺(tái)的特殊性,在本文中將三層架構(gòu)的職責(zé)劃分如下:
數(shù)據(jù)訪問層--負(fù)責(zé)與數(shù)據(jù)源的交互,即數(shù)據(jù)的插入、刪除、修改以及從數(shù)據(jù)庫中讀出數(shù)據(jù)等操作。對(duì)數(shù)據(jù)的正確性和有效性不負(fù)責(zé),對(duì)數(shù)據(jù)的用途不了解,不負(fù)擔(dān)任何業(yè)務(wù)邏輯。業(yè)務(wù)邏輯層--負(fù)責(zé)系統(tǒng)領(lǐng)域業(yè)務(wù)的處理,負(fù)責(zé)邏輯性數(shù)據(jù)的生成、處理及轉(zhuǎn)換。對(duì)流入的邏輯性數(shù)據(jù)的正確性及有效性負(fù)責(zé),對(duì)流出的邏輯性數(shù)據(jù)及用戶性數(shù)據(jù)不負(fù)責(zé),對(duì)數(shù)據(jù)的呈現(xiàn)樣式不負(fù)責(zé)。表示層-—負(fù)責(zé)接收用戶的輸入、將輸出呈現(xiàn)給用戶以及訪問安全性驗(yàn)證。對(duì)流入的數(shù)據(jù)的正確性和有效性負(fù)責(zé),對(duì)呈現(xiàn)樣式負(fù)責(zé),對(duì)流出的數(shù)據(jù)正確性不負(fù)責(zé),但負(fù)責(zé)在數(shù)據(jù)不正確時(shí)給出相應(yīng)的異常信息。模塊劃分及交互設(shè)計(jì):綜合以上分析,可在宏觀上將整個(gè)系統(tǒng)分為一下幾個(gè)模塊:實(shí)體類模塊-—一組實(shí)體類的集合,負(fù)責(zé)整個(gè)系統(tǒng)中數(shù)據(jù)的封裝及傳遞。數(shù)據(jù)訪問層接口族——一組接口的集合,表示數(shù)據(jù)訪問層的接口。業(yè)務(wù)邏輯層接口族--一組接口的集合,表示業(yè)務(wù)邏輯層的接口。數(shù)據(jù)訪問層模塊——一組類的集合,完成數(shù)據(jù)訪問層的具體功能,實(shí)現(xiàn)數(shù)據(jù)訪問層接口族。業(yè)務(wù)邏輯層模塊——一組類的集合,完成業(yè)務(wù)邏輯層的具體功能,實(shí)現(xiàn)業(yè)務(wù)邏輯層接口族。表示層模塊——程序及可視元素的集合,負(fù)責(zé)完成表示層的具體功能。IoC容器模塊——負(fù)責(zé)依賴注入的實(shí)現(xiàn)。輔助類模塊——完成全局輔助性功能。各模塊見交互關(guān)系如下:
圖1這篇中理論比較多,但是它是整個(gè)架構(gòu)的基礎(chǔ),可以幫助朋友們對(duì)將要實(shí)現(xiàn)的項(xiàng)目架構(gòu)及要遵循的原則有一個(gè)整體的了解.當(dāng)然,在后續(xù)文章中,將主要討論Demo項(xiàng)目的實(shí)際開發(fā)過程,那時(shí),這些思想和理論性的東西將得到體現(xiàn)。實(shí)體類是現(xiàn)實(shí)實(shí)體在計(jì)算機(jī)中的表示。它貫穿于整個(gè)架構(gòu),負(fù)擔(dān)著在各層次及模塊間傳遞數(shù)據(jù)的職責(zé)。一般來說,實(shí)體類可以分為“貧血實(shí)體類”和“充血實(shí)體類”,前者僅僅保存實(shí)體的屬性,而后者還包含一些實(shí)體間的關(guān)系與邏輯.我們?cè)谶@個(gè)Demo中用的實(shí)體類將是“貧血實(shí)體類"。??
大多情況下,實(shí)體類和數(shù)據(jù)庫中的表(這里指實(shí)體表,不包括表示多對(duì)多對(duì)應(yīng)的關(guān)系表)是一一對(duì)應(yīng)的,但這并不是一個(gè)限制,在復(fù)雜的數(shù)據(jù)庫設(shè)計(jì)中,有可能出現(xiàn)一個(gè)實(shí)體類對(duì)應(yīng)多個(gè)表,或者交叉對(duì)應(yīng)的情況。在本文的Demo中,實(shí)體類和表是一一對(duì)應(yīng)的,并且實(shí)體類中的屬性和表中的字段也是對(duì)應(yīng)的。
?
在看實(shí)體類的代碼前,先看一下系統(tǒng)的工程結(jié)構(gòu)。
如上圖所示,在初始階段,整個(gè)系統(tǒng)包括6個(gè)工程,它們的職責(zé)是這樣的:?
Web—-表示層
Entity——存放實(shí)體類
Factory——存放和依賴注入及IoC相關(guān)的類
IBLL——存放業(yè)務(wù)邏輯層接口族?
IDAL-—存放數(shù)據(jù)訪問層接口族?
Utility--存放各種工具類及輔助類
?
這只是一個(gè)初期架構(gòu),主要是將整個(gè)系統(tǒng)搭一個(gè)框架,在后續(xù)開發(fā)中,將會(huì)有其他工程被陸陸續(xù)續(xù)添加進(jìn)來.
我們的實(shí)體類將放在Entity工程下,這里包括三個(gè)文件:AdminInfo.cs,MessageInfo。cs,CommentInfo。cs,分別是管理員實(shí)體類、留言實(shí)體類和評(píng)論實(shí)體類。具體代碼如下:
AdminInfo。cs:
1using
System;
2
3namespace
NGuestBook.Entity
4{?
5
///
<summary>
6
///
實(shí)體類—管理員?
7
///
</summary>
8
[Serializable]?
9
public
class
AdminInfo?10
{
11
private
int
id;
12
private
string
name;
13
private
string
password;
1415
public
int
ID?16
{
17
get
{
return
this.id;
}
18
set
{
this。id
=
value;
}?19
}?2021
public
string
Name
22
{
23
get
{
return
this.name;
}
24
set
{
this.name
=
value;
}
25
}?2627
public
string
Password?28
{
29
get
{
return
this.password;
}?30
set
{
this.password
=
value;
}
31
}?32
}
33}
34
MessageInfo.cs:
1using
System;
2
3namespace
NGuestBook。Entity
4{
5
///
〈summary>
6
///
實(shí)體類-留言?
7
///
〈/summary〉
8
[Serializable]
9
public
class
MessageInfo?10
{
11
private
int
id;
12
private
string
guestName;
13
privat(yī)e
string
guestEmail;
14
private
string
content;
15
privat(yī)e
DateTime
time;?16
private
string
reply;?17
private
string
isPass;?1819
public
int
ID?20
{
21
get
{
return
this.id;
}?22
set
{
this.id
=
value;
}
23
}
2425
public
string
GuestName?26
{
27
get
{
return
this.guestName;
}?28
set
{
this.guestName
=
value;
}?29
}?3031
public
string
GuestEmail?32
{?33
get
{
return
this.guestEmail;
}?34
set
{
this.guestEmail
=
value;
}
35
}?3637
public
string
Content?38
{?39
get
{
return
this。content;
}?40
set
{
this.content
=
value;
}
41
}
4243
public
DateTime
Time
44
{?45
get
{
return
this。time;
}?46
set
{
this.time
=
value;
}
47
}?4849
public
string
Reply?50
{
51
get
{
return
this。reply;
}
52
set
{
this.reply
=
value;
}
53
}?5455
public
string
IsPass?56
{
57
get
{
return
this.isPass;
}?58
set
{
this.isPass
=
value;
}
59
}?60
}
61}?62
CommentInfo.cs:
1using
System;?
2
3namespace
NGuestBook。Entity
4{?
5
///
〈summary>
6
///
實(shí)體類-評(píng)論?
7
///
〈/summary〉
8
[Serializable]
9
public
class
CommentInfo?10
{?11
private
int
id;?12
private
string
content;
13
privat(yī)e
DateTime
time;?14
private
int
message;?1516
public
int
ID
17
{?18
get
{
return
this.id;
}?19
set
{
this.id
=
value;
}
20
}
2122
public
string
Content?23
{?24
get
{
return
this.content;
}
25
set
{
this.content
=
value;
}
26
}
2728
public
Dat(yī)eTime
Time?29
{
30
get
{
return
this.time;
}?31
set
{
this.time
=
value;
}?32
}
3334
public
int
Message
35
{?36
get
{
return
this.message;
}
37
set
{
this。message
=
value;
}
38
}?39
}
40}?41
大家可以看出,實(shí)體類的代碼很簡(jiǎn)單,僅僅是負(fù)責(zé)實(shí)體的表示和數(shù)據(jù)的傳遞,不包含任何邏輯性內(nèi)容。下篇將介紹接口的設(shè)計(jì)。接下來,將進(jìn)行接口的設(shè)計(jì)。這里包括數(shù)據(jù)訪問層接口和業(yè)務(wù)邏輯層接口.在分層架構(gòu)中,接口扮演著非常重要的角色,它不但直接決定了各層中的各個(gè)操作類需要實(shí)現(xiàn)何種操作,而且它明確了各個(gè)層次的職責(zé)。接口也是系統(tǒng)實(shí)現(xiàn)依賴注入機(jī)制不可缺少的部分。
?
本項(xiàng)目的接口設(shè)計(jì)將按如下順序進(jìn)行:?
1.首先由前文的需求分析,列出主要的UI部分.
2.分析各個(gè)UI需要什么業(yè)務(wù)邏輯支持,從而確定業(yè)務(wù)邏輯層接口。?
3。分析業(yè)務(wù)邏輯層接口需要何種數(shù)據(jù)訪問操作,從而確定數(shù)據(jù)訪問層接口。?
另外,為保證完全的面向?qū)ο筇匦?,接口之間的數(shù)據(jù)傳遞主要靠實(shí)體類或?qū)嶓w類集合,禁止使用DataTable等對(duì)象傳遞數(shù)據(jù)。
由需求分析,列出主要UI
需求分析部分,請(qǐng)參看基于。NET平臺(tái)的分層架構(gòu)實(shí)戰(zhàn)(二)——需求分析與數(shù)據(jù)庫設(shè)計(jì)。有需求分析,可以列出系統(tǒng)中主要應(yīng)包括以下UI:?
UI01——主頁面,列出全部的留言及相應(yīng)評(píng)論,支持分頁顯示.留言按發(fā)表時(shí)間逆序顯示,評(píng)論緊跟在相應(yīng)留言下.管理員可以通過相應(yīng)鏈接對(duì)留言執(zhí)行通過驗(yàn)證、刪除、回復(fù)以及對(duì)評(píng)論進(jìn)行刪除操作。游客可通過相應(yīng)連接進(jìn)入發(fā)表留言評(píng)論頁面。?
UI02—-發(fā)表留言頁面,供游客發(fā)表新留言.
UI03--發(fā)表評(píng)論頁面,供游客發(fā)表評(píng)論。
UI04-—回復(fù)留言頁面,供管理員回復(fù)留言.
UI05—-管理員登錄頁面。
UI06-—管理員修改個(gè)人密碼的頁面。
UI07——超級(jí)管理員登錄后的頁面,主要提供管理員列表??梢酝ㄟ^相應(yīng)鏈接將指定管理員刪除。?
UI08—-添加新管理員的頁面。
UI09-—操作成功完成后的跳轉(zhuǎn)提示頁面。
UI10——系統(tǒng)出現(xiàn)異常時(shí)顯示友好出錯(cuò)信息的頁面。?
由UI識(shí)別業(yè)務(wù)邏輯操作
UI01:按分頁取得留言,按指定留言取得全部評(píng)論,將指定留言通過驗(yàn)證,將指定留言刪除,將指定評(píng)論刪除
UI02:添加新留言
UI03:添加新評(píng)論
UI04:回復(fù)留言
UI05:管理員登錄?
UI06:修改管理員密碼?
UI07:取得全部管理員信息,刪除管理員?
UI08:添加新管理員?
經(jīng)過整理,可得以下接口操作:
IAdminBLL:Add(添加管理員),Remove(刪除管理員),ChangePassword(修改管理員密碼),Login(管理員登錄),GetAll(取得全部管理員)
IMessageBLL:Add(添加留言),Remove(刪除留言),Revert(回復(fù)留言),Pass(將留言通過驗(yàn)證),GetByPage(按分頁取得留言)?
ICommentBLL:Add(添加評(píng)論),Remove(刪除評(píng)論),GetByMessage(按留言取得全部評(píng)論)
這三個(gè)接口文件都放在IBLL工程下,具體代碼如下:
?IAdminBLL.cs:
1using
System;?
2using
System.Collections.Generic;?
3using
System.Text;
4using
NGuestBook。Entity;?
5
6namespace
NGuestBook.IBLL?
7{
8
///
〈summary>
9
///
業(yè)務(wù)邏輯層接口—管理員?10
///
〈/summary〉11
public
interface
IAdminBLL?12
{
13
///
<summary〉14
///
添加管理員
15
///
</summary〉16
///
〈param
name=”admin">新管理員實(shí)體類</param〉17
///
<returns>是否成功</returns>18
bool
Add(AdminInfo
admin);?1920
///
〈summary>21
///
刪除管理員?22
///
</summary>23
///
<param
name="id”〉欲刪除的管理員的ID</param>24
///
<returns>是否成功〈/returns>25
bool
Remove(int
id);
2627
///
〈summary>28
///
修改管理員密碼
29
///
</summary>30
///
<param
name=”id”>欲修改密碼的管理員的ID</param>31
///
〈param
name="password">新密碼〈/param〉32
///
<returns〉是否成功</returns>33
bool
ChangePassword(int
id,string
password);
3435
///
<summary〉36
///
管理員登錄
37
///
</summary>38
///
〈param
name=”name"〉管理員登錄名〈/param〉39
///
<param
name=”password">管理員密碼〈/param>40
///
〈returns〉如果登錄成功,則返回相應(yīng)管理員的實(shí)體類,否則返回null</returns>41
AdminInfo
Login(string
name,string
password);?4243
///
<summary〉44
///
取得全部管理員信息?45
///
</summary>46
///
<returns〉管理員實(shí)體類集合</returns〉47
IList〈AdminInfo>
GetAll();
48
}?49}?IMessageBLL.cs:
1using
System;
2using
System.Collections。Generic;
3using
System。Text;
4using
NGuestBook.Entity;
5
6namespace
NGuestBook.IBLL?
7{
8
///
〈summary〉
9
///
業(yè)務(wù)邏輯層接口—留言?10
///
</summary>11
public
interface
IMessageBLL?12
{?13
///
<summary>14
///
添加留言?15
///
〈/summary>16
///
〈param
name=”message">新留言實(shí)體類〈/param>17
///
<returns>是否成功〈/returns>18
bool
Add(MessageInfo
message);?1920
///
〈summary〉21
///
刪除留言?22
///
</summary>23
///
<param
name="id"〉欲刪除的留言的ID</param>24
///
<returns>是否成功</returns>25
bool
Remove(int
id);
2627
///
〈summary>28
///
回復(fù)留言?29
///
</summary>30
///
〈param
name="id”〉要回復(fù)的留言的ID</param>31
///
<param
name=”reply">回復(fù)信息</param〉32
///
<returns>是否成功〈/returns>33
bool
Revert(int
id,
string
reply);?3435
///
<summary〉36
///
將留言通過驗(yàn)證
37
///
〈/summary>38
///
<param
name=”id">通過驗(yàn)證的留言的ID</param>39
///
<returns〉是否成功</returns〉40
bool
Pass(int
id);?4142
///
<summary〉43
///
按分頁取得留言信息?44
///
〈/summary〉45
///
〈param
name=”pageSize"〉每頁顯示幾條留言〈/param〉46
///
<param
name="pageNumber"〉當(dāng)前頁碼</param>47
///
<returns>留言實(shí)體類集合</returns〉48
IList〈MessageInfo>
GetByPage(int
pageSize,int
pageNumber);?49
}?50}
ICommentBLL。cs
1using
System;
2using
System。Collections。Generic;
3using
System.Text;
4using
NGuestBook.Entity;?
5
6namespace
NGuestBook.IBLL
7{
8
///
〈summary>
9
///
業(yè)務(wù)邏輯層接口-評(píng)論
10
///
</summary>11
public
interface
ICommentBLL?12
{?13
///
<summary〉14
///
添加評(píng)論
15
///
</summary>16
///
<param
name="comment”〉新評(píng)論實(shí)體類</param>17
///
<returns>是否成功</returns>18
bool
Add(CommentInfo
comment);
1920
///
〈summary〉21
///
刪除評(píng)論?22
///
〈/summary〉23
///
〈param
name="id"〉欲刪除的評(píng)論的ID</param〉24
///
<returns〉是否成功</returns>25
bool
Remove(int
id);
2627
///
<summary〉28
///
取得指定留言的全部評(píng)論?29
///
</summary>30
///
<param
name="messageId”>指定留言的ID</param〉31
///
〈returns>評(píng)論實(shí)體類集合</returns〉32
IList〈CommentInfo>
GetByMessage(int
messageId);
33
}?34}?
?
由業(yè)務(wù)邏輯確定數(shù)據(jù)訪問操作
IAdminBLL需要的數(shù)據(jù)訪問操作:插入管理員,刪除管理員,更新管理員信息,按ID取得管理員信息,按登錄名與密碼取得管理員,取得全部管理員
IMessageBLL需要的數(shù)據(jù)訪問操作:插入留言,刪除留言,更新留言信息,按ID取得留言信息,按分頁取得留言?
ICommentBLL需要的數(shù)據(jù)訪問操作:插入評(píng)論,刪除評(píng)論,按留言取得全部評(píng)論
另外,添加管理員時(shí)需要驗(yàn)證是否存在同名管理員,所以需要添加一個(gè)“按登錄名取得管理員”.
對(duì)以上操作進(jìn)行整理,的如下接口操作:
IAdminDAL:Insert,Delete,Update,GetByID,GetByNameAndPassword,GetAll?
IMessageDAL:Insert,Delete,Update,GetByID,GetByPage?
ICommentDAL:Insert,Delete,GetByMessage
這三個(gè)接口文件放在IDAL工程下,具體代碼如下:??IAdminDAL。cs:
1using
System;?
2using
System.Collections。Generic;
3using
System.Text;?
4using
NGuestBook.Entity;?
5
6namespace
NGuestBook.IDAL
7{?
8
///
〈summary>
9
///
數(shù)據(jù)訪問層接口-管理員?10
///
</summary〉11
public
interface
IAdminDAL
12
{
13
///
<summary>14
///
插入管理員
15
///
</summary〉16
///
<param
name="admin">管理員實(shí)體類</param〉17
///
<returns〉是否成功〈/returns〉18
bool
Insert(AdminInfo
admin);?1920
///
<summary>21
///
刪除管理員?22
///
</summary〉23
///
〈param
name="id">欲刪除的管理員的ID</param>24
///
〈returns>是否成功</returns>25
bool
Delete(int
id);
2627
///
<summary〉28
///
更新管理員信息?29
///
</summary>30
///
〈param
name="admin">管理員實(shí)體類〈/param〉31
///
〈returns>是否成功</returns〉32
bool
Update(AdminInfo
admin);?3334
///
<summary〉35
///
按ID取得管理員信息?36
///
</summary〉37
///
<param
name=”id">管理員ID</param〉38
///
<returns〉管理員實(shí)體類</returns〉39
AdminI(lǐng)nfo
GetByID(int
id);
4041
///
〈summary〉42
///
按管理員名取得管理員信息
43
///
〈/summary>44
///
<param
name="name"〉管理員名〈/param〉45
///
<returns〉管理員實(shí)體類</returns〉46
AdminI(lǐng)nfo
GetByName(string
name);
4748
///
<summary>49
///
按用戶名及密碼取得管理員信息
50
///
</summary>51
///
<param
name="name”>用戶名</param>52
///
<param
name=”password">密碼</param>53
///
<returns>管理員實(shí)體類,不存在時(shí)返回null</returns>54
AdminInfo
GetByNameAndPassword(string
name,string
password);
5556
///
〈summary>57
///
取得全部管理員信息
58
///
〈/summary>59
///
<returns〉管理員實(shí)體類集合</returns〉60
IList<AdminI(lǐng)nfo>
GetAll();?61
}
62}
IMessageDAL.cs:
1using
System;
2using
System.Collections。Generic;
3using
System.Text;?
4using
NGuestBook。Entity;
5
6namespace
NGuestBook.IDAL
7{?
8
///
<summary〉
9
///
數(shù)據(jù)訪問層接口-留言?10
///
</summary〉11
public
interface
IMessageDAL?12
{
13
///
〈summary>14
///
插入留言
15
///
〈/summary〉16
///
<param
name="message">留言實(shí)體類</param>17
///
〈returns>是否成功〈/returns>18
bool
Insert(MessageInfo
message);
1920
///
<summary>21
///
刪除留言
22
///
</summary>23
///
〈param
name=”id">欲刪除的留言的ID</param〉24
///
〈returns〉是否成功〈/returns〉25
bool
Delete(int
id);
2627
///
<summary〉28
///
更新留言信息?29
///
</summary〉30
///
<param
name="message”〉留言實(shí)體類〈/param>31
///
〈returns〉是否成功〈/returns>32
bool
Updat(yī)e(MessageInfo
message);
3334
///
<summary〉35
///
按ID取得留言信息?36
///
</summary>37
///
〈param
name="id”〉留言ID〈/param〉38
///
<returns>留言實(shí)體類〈/returns>39
MessageInfo
GetByID(int
id);?4041
///
<summary〉42
///
按分頁取得留言信息?43
///
</summary>44
///
〈param
name="pageSize"〉每頁顯示幾條留言</param〉45
///
〈param
name="pageNumber"〉當(dāng)前頁碼</param>46
///
<returns>留言實(shí)體類集合</returns>47
IList<MessageInfo>
GetByPage(int
pageSize,int
pageNumber);
48
}
49}?ICommentDAL。cs:
1using
System;
2using
System.Collections.Generic;
3using
System.Text;
4using
NGuestBook.Entity;?
5
6namespace
NGuestBook.IDAL?
7{
8
///
〈summary>
9
///
數(shù)據(jù)訪問層接口-評(píng)論?10
///
</summary>11
public
interface
ICommentDAL?12
{
13
///
<summary>14
///
插入評(píng)論
15
///
〈/summary>16
///
〈param
name="comment"〉評(píng)論實(shí)體類〈/param>17
///
〈returns>是否成功</returns〉18
bool
Insert(CommentInfo
comment);
1920
///
〈summary〉21
///
刪除評(píng)論?22
///
〈/summary>23
///
<param
name=”id”〉欲刪除的評(píng)論的ID</param>24
///
〈returns>是否成功</returns〉25
bool
Delete(int
id);
2627
///
〈summary〉28
///
取得指定留言的全部評(píng)論
29
///
〈/summary〉30
///
〈param
name=”messageId”>指定留言的ID</param>31
///
<returns〉評(píng)論實(shí)體類集合</returns>32
IList〈CommentInfo〉
GetByMessage(int
messageId);
33
}
34}我們?cè)O(shè)計(jì)的分層架構(gòu),層與層之間應(yīng)該是松散耦合的。因?yàn)槭菃蜗騿我徽{(diào)用,所以,這里的“松散耦合”實(shí)際是指上層類不能具體依賴于下層類,而應(yīng)該依賴于下層提供的一個(gè)接口.這樣,上層類不能直接實(shí)例化下層中的類,而只持有接口,至于接口所指變量最終究竟是哪一個(gè)類,則由依賴注入機(jī)制決定。??
之所以這樣做,是為了實(shí)現(xiàn)層與層之間的“可替換”式設(shè)計(jì),例如,現(xiàn)在需要換一種方式實(shí)現(xiàn)數(shù)據(jù)訪問層,只要這個(gè)實(shí)現(xiàn)遵循了前面定義的數(shù)據(jù)訪問層接口,業(yè)務(wù)邏輯層和表示層不需要做任何改動(dòng),只需要改一下配置文件系統(tǒng)即可正常運(yùn)行.另外,基于這種結(jié)構(gòu)的系統(tǒng),還可以實(shí)現(xiàn)并行開發(fā)。即不同開發(fā)人員可以專注于自己的層次,只有接口被定義好了,開發(fā)出來的東西就可以無縫連接。?
在J2EE平臺(tái)上,主要使用Spring框架實(shí)現(xiàn)依賴注入。這里,我們將自己做一個(gè)依賴注入容器。
?
依賴注入的理論基礎(chǔ)是AbstractFactory設(shè)計(jì)模式,這里結(jié)合具體實(shí)例簡(jiǎn)單介紹一下。?
上圖以數(shù)據(jù)訪問層為例,展示了AbstractFactory模式的應(yīng)用。如圖,現(xiàn)假設(shè)有針對(duì)Access和SQLServer兩種數(shù)據(jù)庫的數(shù)據(jù)訪問層,它們都實(shí)現(xiàn)了數(shù)據(jù)訪問層接口。每個(gè)數(shù)據(jù)訪問層有自己的工廠,所有工廠都實(shí)現(xiàn)自IDALFactory接口。而客戶類(這里就是業(yè)務(wù)邏輯層類)僅與工廠接口、數(shù)據(jù)訪問層接口耦合,而與具體類無關(guān),這樣,只要通過配置文件確定實(shí)例化哪個(gè)工廠,就可以得到不同的數(shù)據(jù)訪問層.
?
然而,這種設(shè)計(jì)雖然可行,但是代碼比較冗余,因?yàn)檫@樣需要為數(shù)據(jù)訪問層的每一個(gè)實(shí)現(xiàn)編寫一個(gè)工廠,業(yè)務(wù)邏輯層也一樣。在以前,我們毫無辦法,但是,。NET平臺(tái)引入的反射機(jī)制,給我們提供了一種解決方案。使用反射,每個(gè)層只需要一個(gè)工廠,然后通過從配置文件中讀出程序集的名稱,動(dòng)態(tài)加載相應(yīng)類。另外,為了提高依賴注入機(jī)制的效率,這里引入緩存機(jī)制。下面來看具體實(shí)現(xiàn)。
?
配置
首先,需要在Web工程的Web.config文件的〈appSettings〉節(jié)點(diǎn)下添加如下兩個(gè)項(xiàng):
<addkey="DAL"value="”/>?
〈addkey=”BLL"value=""/〉
這兩個(gè)配置選項(xiàng)分別存儲(chǔ)要應(yīng)用的數(shù)據(jù)訪問和也業(yè)務(wù)邏輯層的程序集名稱。value目前是空,是因?yàn)槟壳斑€沒有各個(gè)層次的具體實(shí)現(xiàn)。
?
實(shí)現(xiàn)緩存操作輔助類
為實(shí)現(xiàn)緩存操作,我們將緩存操作封裝成一個(gè)輔助類,放在Utility工程下,具體代碼如下:
?CacheAccess.cs:
封裝依賴注入代碼
因?yàn)楹芏嘁蕾囎⑷氪a非常相似,為了減少重復(fù)性代碼,我們將可復(fù)用的代碼先封裝在一個(gè)類中。具體代碼如下(這個(gè)類放在Factory工程下):
DependencyInjector.cs:
1using
System;
2using
System。Web;?
3using
System.Web.Caching;?
4
5namespace
NGuestBook.Utility?
6{
7
///
<summary〉
8
///
輔助類,用于緩存操作?
9
///
〈/summary〉10
public
sealed
class
CacheAccess
11
{?12
///
<summary〉13
///
將對(duì)象加入到緩存中?14
///
〈/summary〉15
///
<param
name=”cacheKey"〉緩存鍵</param〉16
///
<param
name="cacheObject"〉緩存對(duì)象</param>17
///
〈param
name="dependency"〉緩存依賴項(xiàng)</param〉18
public
static
void
SaveToCache(string
cacheKey,
object
cacheObject,
CacheDependency
dependency)?19
{
20
Cache
cache
=
HttpRuntime。Cache;
21
cache。Insert(cacheKey,
cacheObject,
dependency);
22
}?2324
///
<summary>25
///
從緩存中取得對(duì)象,不存在則返回null
26
///
〈/summary>27
///
〈param
name="cacheKey"〉緩存鍵</param>28
///
<returns>獲取的緩存對(duì)象</returns>29
public
static
object
GetFromCache(string
cacheKey)?30
{?31
Cache
cache
=
HttpRuntime。Cache;?3233
return
cache[cacheKey];?34
}
35
}?36}
1using
System;?
2using
System。Configuration;?
3using
System.Reflection;?
4using
System.Web;?
5using
System.Web.Caching;
6using
NGuestBook.Utility;?
7
8namespace
NGuestBook。Factory?
9{?10
///
〈summary〉11
///
依賴注入提供者?12
///
使用反射機(jī)制實(shí)現(xiàn)?13
///
</summary>14
public
sealed
class
DependencyInjector?15
{?16
///
<summary>17
///
取得數(shù)據(jù)訪問層對(duì)象?18
///
首先檢查緩存中是否存在,如果不存在,則利用反射機(jī)制返回對(duì)象
19
///
</summary〉20
///
〈param
name=”className">數(shù)據(jù)訪問類名稱</param〉21
///
<returns>數(shù)據(jù)訪問層對(duì)象〈/returns〉22
public
stat(yī)ic
object
GetDALObject(string
className)
23
{?24
///
〈summary>25
///
取得數(shù)據(jù)訪問層名稱,首先檢查緩存,不存在則到配置文件中讀取
26
///
緩存依賴項(xiàng)為Web.Config文件
27
///
〈/summary>28
object
dal
=
CacheAccess.GetFromCache(”DAL");?29
if
(dal
==
null)
30
{?31
CacheDependency
fileDependency
=
new
CacheDependency(HttpContext.Current。Server.MapPath(”Web.Config"));
32
dal
=
ConfigurationManager.AppSettings["DAL”];?33
CacheAccess.SaveToCache(”DAL",
dal,
fileDependency);
34
}
3536
///
<summary>37
///
取得數(shù)據(jù)訪問層對(duì)象?38
///
〈/summary>39
string
dalName
=
(string)dal;?40
string
fullClassName
=
dalName
+
"。"
+
className;
41
object
dalObject
=
CacheAccess.GetFromCache(className);?42
if
(dalObject
==
null)?43
{
44
CacheDependency
fileDependency
=
new
CacheDependency(HttpContext.Current.Server.MapPath("Web.Config"));
45
dalObject
=
Assembly。Load(dalName)。CreateInstance(fullClassName);?46
CacheAccess.SaveToCache(className,
dalObject,
fileDependency);?47
}?4849
return
dalObject;?50
}
5152
///
〈summary〉53
///
取得業(yè)務(wù)邏輯層對(duì)象
54
///
首先檢查緩存中是否存在,如果不存在,則利用反射機(jī)制返回對(duì)象?55
///
〈/summary〉56
///
<param
name=”className">業(yè)務(wù)邏輯類名稱</param>57
///
<returns〉業(yè)務(wù)邏輯層對(duì)象</returns>58
public
stat(yī)ic
object
GetBLLObject(string
className)
59
{
60
///
<summary>61
///
取得業(yè)務(wù)邏輯層名稱,首先檢查緩存,不存在則到配置文件中讀取?62
///
緩存依賴項(xiàng)為Web。Config文件?63
///
〈/summary>64
object
bll
=
CacheAccess.GetFromCache(”BLL");?65
if
(bll
==
null)
66
{
67
CacheDependency
fileDependency
=
new
CacheDependency(HttpContext.Current.Server.MapPath("Web.Config"));
68
bll
=
Configurat(yī)ionManager.AppSettings[”BLL"];?69
CacheAccess.SaveToCache("BLL",
bll,
fileDependency);
70
}
7172
///
<summary>73
///
取得業(yè)務(wù)邏輯層對(duì)象
74
///
</summary>75
string
bllName
=
(string)bll;?76
string
fullClassName
=
bllName
+
”."
+
className;
77
object
bllObject
=
CacheAccess。GetFromCache(className);
78
if
(bllObject
==
null)
79
{?80
CacheDependency
fileDependency
=
new
CacheDependency(HttpContext。Current.Server.MapPath("Web.Config"));
81
bllObject
=
Assembly.Load(bllName).CreateInstance(fullClassName);
82
CacheAccess.SaveToCache(className,
bllObject,
fileDependency);?83
}?8485
return
bllObject;
86
}
87
}?88}
實(shí)現(xiàn)工廠
下面使用兩個(gè)輔助類,實(shí)現(xiàn)數(shù)據(jù)訪問層工廠和業(yè)務(wù)邏輯層工廠.??DALFactory。cs
1using
System;?
2using
NGuestBook.IDAL;?
3
4namespace
NGuestBook.Factory?
5{
6
///
〈summary>
7
///
數(shù)據(jù)訪問層工廠,用于獲取相應(yīng)的數(shù)據(jù)訪問層對(duì)象
8
///
使用Abstract
Factory設(shè)計(jì)模式+Facace設(shè)計(jì)模式+反射機(jī)制+緩存機(jī)制設(shè)計(jì)
9
///
</summary>10
public
sealed
class
DALFactory?11
{
12
///
<summary>13
///
獲取管理員數(shù)據(jù)訪問層對(duì)象?14
///
</summary>15
///
<returns>管理員數(shù)據(jù)訪問層對(duì)象〈/returns〉16
public
static
IAdminDAL
CreateAdminDAL()?17
{?18
return
(IAdminDAL)DependencyInjector.GetDALObject("AdminDAL”);?19
}?2021
///
〈summary>22
///
獲取留言數(shù)據(jù)訪問層對(duì)象
23
///
</summary〉24
///
<returns>留言數(shù)據(jù)訪問層對(duì)象</returns〉25
public
static
IMessageDAL
Creat(yī)eMessageDAL()
26
{?27
return
(IMessageDAL)DependencyInjector.GetDALObject("MessageDAL");?28
}?2930
///
<summary>31
///
獲取評(píng)論數(shù)據(jù)訪問層對(duì)象
32
///
〈/summary>33
///
<returns>評(píng)論數(shù)據(jù)訪問層對(duì)象</returns〉34
public
static
ICommentDAL
Creat(yī)eCommentDAL()
35
{
36
return
(ICommentDAL)DependencyInjector.GetDALObject("CommentDAL”);?37
}
38
}
39}?BLLFactory.cs
1using
System;
2using
NGuestBook。IBLL;
3
4namespace
NGuestBook。Factory?
5{?
6
///
<summary〉
7
///
業(yè)務(wù)邏輯層工廠,用于獲取相應(yīng)的業(yè)務(wù)邏輯層對(duì)象
8
///
使用Abstract
Factory設(shè)計(jì)模式+Facace設(shè)計(jì)模式+反射機(jī)制+緩存機(jī)制設(shè)計(jì)?
9
///
</summary>10
public
sealed
class
BLLFactory?11
{?12
///
<summary>13
///
獲取管理員業(yè)務(wù)邏輯層對(duì)象?14
///
</summary>15
///
〈returns〉管理員業(yè)務(wù)邏輯層對(duì)象〈/returns>16
public
static
IAdminBLL
CreateAdminBLL()
17
{?18
return
(IAdminBLL)DependencyInjector.GetBLLObject(”AdminBLL”);
19
}?2021
///
<summary〉22
///
獲取留言業(yè)務(wù)邏輯層對(duì)象?23
///
</summary>24
///
<returns〉留言業(yè)務(wù)邏輯層對(duì)象〈/returns>25
public
static
IMessageBLL
CreateMessageBLL()
26
{
27
return
(IMessageBLL)DependencyInjector。GetBLLObject("MessageBLL”);
28
}?2930
///
<summary>31
///
獲取評(píng)論業(yè)務(wù)邏輯層對(duì)象
32
///
〈/summary〉33
///
〈returns>評(píng)論業(yè)務(wù)邏輯層對(duì)象</returns>34
public
static
ICommentBLL
CreateCommentBLL()
35
{?36
return
(ICommentBLL)DependencyInjector.GetBLLObject("CommentBLL");?37
}
38
}
39}經(jīng)過上面篇文章的介紹,整個(gè)系統(tǒng)的框架算是基本搭建完了,下面,我們要具體實(shí)現(xiàn)各個(gè)層次。關(guān)于數(shù)據(jù)訪問層的實(shí)現(xiàn),我準(zhǔn)備討論三種實(shí)現(xiàn)方式,這一篇文章討論第一種:Access+動(dòng)態(tài)生成SQL。
顧名思義,這種實(shí)現(xiàn)將使用Access作為后臺(tái)數(shù)據(jù)庫,而操作方式也是最基本的使用SQL命令.?
在具體編寫實(shí)現(xiàn)代碼之前,我們需要做一些準(zhǔn)備工作:
?
第一步,我們要將Access數(shù)據(jù)庫搭建完成,具體做法如下.
在Web工程下新建一個(gè)文件夾,命名為AccessDat(yī)a,并在其中新建一個(gè)mdb文件(即Access數(shù)據(jù)庫文件),按照前面介紹過的數(shù)據(jù)庫設(shè)計(jì)構(gòu)架,將數(shù)據(jù)表及表間關(guān)系建好,這里不再贅述。
第二步,我們要進(jìn)行一些配置。
打開Web工程下的Web.config文件,在其中的appSettings節(jié)點(diǎn)下,添加如下鍵值:
<addkey="AccessConnectionString"value="Provider=Microsoft.Jet。OLEDB.4。0;DataSource={DBPath}"/>?
<addkey="AccessPath”value="~/AccessData/AccessDatabase.mdb"/>?
第一條為Access的連接字符串,第二條為Access數(shù)據(jù)庫文件的路徑,其中“~”表示網(wǎng)站根目錄。
?
第三步,新建一個(gè)工程.?
我們要新建一個(gè)工程AccessDAL,用來存放Access數(shù)據(jù)訪問層的代碼。?
準(zhǔn)備工作做完了,現(xiàn)在來實(shí)現(xiàn)具體的代碼.?
1.編寫數(shù)據(jù)訪問助手類
因?yàn)楹芏鄶?shù)據(jù)訪問操作流程很相似,所以,這里將一些可復(fù)用的代碼抽取出來,編寫成助手類,以此減少代碼量,提高代碼復(fù)用性.?
這個(gè)助手類放在AccessDAL下,叫AccessDALHelper,主要負(fù)責(zé)Access數(shù)據(jù)庫的訪問。它包括三個(gè)方法:?
GetConnectionString:從配置文件中讀取配置項(xiàng),組合成連接字符串.
ExecuteSQLNonQuery:執(zhí)行指定SQL語句,不返回任何值,一般用于Insert,Delete,Update命令.
ExecuteSQLDat(yī)aReader:執(zhí)行SQL語句返回查詢結(jié)果,一般用于Select命令。?
具體代碼如下:
?AccessDALHelper。cs:?
2。實(shí)現(xiàn)具體的數(shù)據(jù)訪問操作類?
因?yàn)榍懊嬉呀?jīng)定義了數(shù)據(jù)訪問層接口,所以實(shí)現(xiàn)數(shù)據(jù)訪問操作類就是很機(jī)械的工作了。下面僅以Admin的數(shù)據(jù)訪問操作類為例:??AdminDAL:
1using
System;
2using
System.Web;
3using
System。Web。Caching;?
4using
System.Configuration;
5using
System.Data;?
6using
System.Data.OleDb;?
7using
NGuestBook.Utility;?
8
9namespace
NGuestBook.AccessDAL
10{
11
///
<summary>12
///
Access數(shù)據(jù)庫操作助手?13
///
〈/summary〉14
public
sealed
class
AccessDALHelper
15
{?16
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《海的女兒》讀后感
- 鄉(xiāng)村醫(yī)生主要先進(jìn)事跡(6篇)
- 鄉(xiāng)鎮(zhèn)老齡工作總結(jié)范文
- 中秋節(jié)活動(dòng)心得體會(huì)(5篇)
- 新學(xué)期學(xué)習(xí)計(jì)劃范例匯編7篇
- 在銀行的實(shí)習(xí)報(bào)告范文錦集七篇
- 世博會(huì)觀后感
- 高等數(shù)學(xué)教程 上冊(cè) 第4版 習(xí)題及答案 P146 第6章 定積分及其應(yīng)用
- 幼兒誠(chéng)信課件教學(xué)課件
- 做好課堂課件教學(xué)課件
- 京東通天塔系統(tǒng)操作說明
- 家庭照護(hù)員題庫
- 鐵道概論高職PPT完整全套教學(xué)課件
- 肩關(guān)節(jié)周圍炎的治療與護(hù)理
- 吉他小白的彈奏秘籍:指彈吉他入門教程
- 自然災(zāi)害之寒潮災(zāi)害演示文稿
- 空壓機(jī)壓縮空氣管道系統(tǒng)施工方案f
- 新版貨物質(zhì)押監(jiān)管合作協(xié)議書范本
- 學(xué)校食品安全總監(jiān)職責(zé),學(xué)校食品安全員守則,學(xué)校食品安全風(fēng)險(xiǎn)日管控、周排查、月調(diào)度工作制度
- 堅(jiān)持以人民為中心發(fā)展思想
- (部編版)二年級(jí)語文上冊(cè)必背課文默寫填空
評(píng)論
0/150
提交評(píng)論