基于.NET平臺(tái)的分層架構(gòu)實(shí)戰(zhàn)(完整資料)_第1頁
基于.NET平臺(tái)的分層架構(gòu)實(shí)戰(zhàn)(完整資料)_第2頁
基于.NET平臺(tái)的分層架構(gòu)實(shí)戰(zhàn)(完整資料)_第3頁
基于.NET平臺(tái)的分層架構(gòu)實(shí)戰(zhàn)(完整資料)_第4頁
基于.NET平臺(tái)的分層架構(gòu)實(shí)戰(zhàn)(完整資料)_第5頁
已閱讀5頁,還剩93頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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{?

///

<summary>

///

實(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;

3namespace

NGuestBook。Entity

4{

5

///

〈summary>

6

///

實(shí)體類-留言?

///

〈/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{?

///

〈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;

6namespace

NGuestBook.IBLL?

7{

8

///

〈summary〉

///

業(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;?

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>

///

數(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{?

///

<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{

///

〈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〉

///

輔助類,用于緩存操作?

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;?

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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論