熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

深入ASP.NET 2.0的提供者模型

2013-11-13 09:54:57  來源: .NET編程 

   引言
  
    早在我就著手開發一個ASPNET在線消息板應用程序WebForumsNET其目的是創建一個基於ASPNET的消息板系統而且該系統可以容易插入到一個現有網站中構建這樣一個端對端應用程序的特別挑戰之一就是要為客戶提供一種方式以便能夠把它集成到他們自己的系統中去例如一個在線論壇明顯需要使用某種數據存儲來存儲用戶信息論壇回寄信息等但是最好不要把客戶鎖定到一種特定的數據存儲中也就是說你不應該說我的應用程序必須使用微軟的SQL Server 因為這樣的話使用Oracle或Access的客戶怎麼會使用你的軟件呢?
  
    另一個集成到客戶現有數據中的問題是所有的在線論壇站點都提供用戶帳戶和一種創建新帳戶的方式典型情況下這被建模為一個論壇架構(以一個數據庫中的Users表形式存在)但是客戶很可能已經有他們自己的擁有成千的用戶帳戶的數據庫表或者一個客戶可能想在一個內部網設置中使用該論壇並且想使用活動目錄而不是某種數據庫表來認證和存儲用戶信息因此當一個論壇軟件系統創建一個Users數據庫表並對其客戶說這就是你存儲用戶的方式那些已經擁有現有基礎結構和用戶數據的客戶很可能會疏遠這樣的軟件
  
    因此當你使用一種僵硬的API構建一個系統時會產生特別的挑戰一種僵硬的API不是提供一種方式來定制邏輯而是硬編碼實現細節(例如你必須使用SQL Server作為你的後端數據存儲且在這個數據庫有一個Users表並將在其中存儲所有的用戶信息)然而通過使用提供者設計模式你可以輕易地打破這種僵硬借助於提供者設計模式系統架構師只需要定義API至於編程功能則由系統來提供對於一個在線論壇應用程序來說這可能包括一個具有例如Authenticate(usernamepassword)和GetUserDetails(username)等方法的Users類
  
    提供者模型的優秀在於客戶實現方案可以指定一個系統應該使用的定制類這種定制類必須實現系統的良好定義的API但是它允許無縫地插入任何定制實現也就是說一旦定義這個API系統實現者可以創建一個使用SQL Server和一個Users表的默認的具體實現大多數客戶可以直接使用之而不必要作任何修改那些有定制需要的客戶(他們想使用Oracle或以另外一些方式存儲用戶數據)可以創建他們自己的類該類提供必要的功能並且把它們插入到這些客戶的系統中
  
    其實提供者設計模式被應用於整個ASPNET 實現中當然網上也存在一些如何在ASPNET x應用程序中使用這一功能的教程
  
    在本文中我們將詳細探討提供者模型並分析如何把它應用於ASPNET 開發中
  
打破僵硬的API實現
  
    在我早期的WebForumsNET開發中我認識到這種僵硬的API實現將會成為一個問題我的軟件設計目標之一就是盡可能靈活且可定制並且使用戶使用SQL Server而且我的用戶數據模型實現應該看起來充其量只是有些限制性為了克服這些問題我構建了一個包含下面兩部分的系統
  
     一組定義了系統的核心功能的抽象基類
  
     能夠在運行時刻動態地加載一個擴展抽象基類具體地說該代碼負責檢查包含一個<ConfigSetting>節(該節中給出要使用的類的完全限定名)的nfig文件

  借助於這一架構我可以通過一系列抽象基類來定義系統的功能並使用SQL Server 和Users表來提供這些類的具體實現滿足這一配置的客戶可以只管使用該應用程序並且一切將工作良好且不需要他們編寫一行代碼然而那些需要定制的開發者們可以通過創建他們自己的派生自適當的抽象基類的類來實現通過簡單地把該程序集放到應用程序的/bin目錄並更新nfig文件他們可以讓系統使用這個新類具體地說WebForumsNET發行中帶有一個抽象基類DataProvider它清楚地列舉出了系統中的所有方法類似如下
  
  
  
  public abstract class DataProvider
  {
  public abstract bool AuthenticateUser(string usernamestring password);
  public abstract User GetUserInfo(string username);
  
  public static DataProvider Instance()
  {
  
  }
  }
  
  
  
    AuthenticateUser(usernamepassword)和GetUserInfo(username)方法是系統定義的許多方法中的兩個方法的代表而靜態Instance()方法是該DataProvider類的主要實現它包含檢查代表了WebForumsNET配置信息(該信息指示系統要使用的類的全稱限定名)的nfig文件的代碼然後該方法使用反射(和緩沖)來創建該類的一個實例並且把它返回到系統
  
    WebForumsNET發行中還帶有一個派生自DataProvider基類的SqlDataProvider類這個類提供分類方法的具體實現例如SqlDataProvider的所有方法都可以操作存儲於一個SQL Server 數據庫中的數據與用戶相關的方法可以與一個預定義的Users數據庫表一起工作一個想改變後端功能的客戶可以創建他自己的派生自DataProvider的類這些信息都可以展示於nfig文件中(指明應該使用他們的定制類)例如WebForumsNET中的nfig可能包括下列內容
  
  
  
  <WebForumsSettings>
  <add key=DataProviderAssemblyPath value=path />
  <add key=DataProviderClassName value=NamespaceClassname />
  </WebForumsSettings>
  
  
  
    默認情況下這個設置信息引用隨同WebForumsNET一起發行的SqlDataProvider類然而如果一個客戶創建他自己的API實現那麼他可以提供自己的類的細節並且系統會自動地開始使用他的實現來創建默認實現
  
    借助於這一架構使用WebForumsNET的頁面開發者可以使用如下所示的代碼來認證一個用戶
  
  
  
  if (DataProviderInstance()AuthenticateUser(usernamepassword))
  //用戶被認證
  else
  //用戶名/口令無效!
  
  

    當調用DataProviderInstance()方法時上面的配置文件被檢查並且返回適當類的一個實例如果客戶還沒有創建他們自己的實現的話這將是默認的SqlDataProvider類而如果他們已經實現的話它將是他們自己的類一旦DataProviderInstance()方法返回一個適當的提供者實例我們就可以簡單地調用該API的成員(在這個例子中是AuthenticateUser())
  
    WebForumsNET提供者模型一個早期的原型
  
    相對於微軟建議使用的提供者模型Andy的提供者模型含有一些不足一方面WebForumsNET中提供了單個抽象基類所有的API定義都聚集在這個類中其負面作用在於如果一個客戶僅想定制系統的一小部分例如用戶信息的存儲方式那麼他必須提供該系統中所有方法的實現一種更好的方案是為系統中的每一個邏輯實體創建一個抽象基類例如對於一個在線消息板應用程序來說它可能需要一些類如UsersProviderForumsProviderPostsProvider等等然而在你提供給一個客戶的提供者數目之間也存在一個平衡問題更多提供者允許更為細致的系統定制但是也會相應地提高要求的配置標記的數量
  
    另外我已經展示了對WebForumsNET的提供者模型實現代碼的作了進一步改進以便使其更相似於微軟在ASPNET 中所使用的代碼我認為Andy的想法應該是提供者模型的先驅盡管微軟的提供者模型實現更為清晰且更強壯一些
  
    一方面WebForumsNET在年三月為微軟所收購另一方面Rob Howard及其他人又在系統中加入了大量的新特征並且在ASPNET論壇中以自由方式發行它Today Rob及其小組成員已經把ASPNET論壇變成了一個Community Server(它簡直把博客論壇畫廊列表服務器新聞閱讀器等全部融為一體)今天Andy所創建的概念與實現被廣泛應用於ASPNET論壇和Community Server中甚至被應用於許多核心ASPNET 組件中 

提供者模型優點
  
    提供者模型提供許多優點首先在代碼和後端實現之間存在清晰的分離不管認證一個用戶的代碼是針對一個SQL Server 數據庫的Users表還是針對於一個活動目錄存儲從頁面開發者的觀察看來代碼都是相同的
  
  DataProviderInstance()AuthenticateUser(usernamepassword)
  
    而且後端實現變化是透明的
  
    因為系統架構師被鼓勵創建默認的實現所以提供者模型提供了兩種世界的最好結合如果對默認實現已經比較滿意那麼系統會按預期進行工作對於需要定制系統的用戶來說他們盡管定制好了而不必干擾現有代碼或編程邏輯這個設計模式也使得原型化和靈敏開發容易許多例如在早期系統使用階段僅使用默認實現可能更容易然而以後你可能需要定制某些方面以便把該工作與你的公司的現有系統集成到一起這時你可以通過提供者模型實現需要的定制這意味著不需要改變你的早期工作來反映後端實現的變化
  
    就象許多好的設計模型一樣提供者模型也提供了開發者之間的職責分離這樣以來一部分開發者可以使用他們精通的系統API進行工作而另一部分開發者可以專注於後端實現和定制任務開發而且這兩組人員可以工作在同一個系統上而不會相互干擾而且如果他們所使用的系統是一種工業標准(例如ASPNET 那麼這兩類任務中的技能都可以被容易地移植到未來的工作中
  
ASPNET 提供者模型
  
    ASPNET 在全部其架構中都利用提供者模型例如它的許多子系統會員站點導航個性化等都利用了提供者模型技術而且每個子系統都提供一種默認實現但也能使客戶定制其功能以滿足他們自己的需要例如ASPNET 的站點導航部分允許一個頁面開發者定義他們網站的可導航的結構然後這些數據就可以被各種Web控件所使用以便顯示站點地圖樹狀視圖或菜單它們能夠高亮站點的導航並且/或者顯示用戶的站點位置除了與導航相關的Web控件外站點導航API還提供了一組方法用於實現與網站導航信息的交互
  
    默認地站點的可導航信息必須以一個正確格式化的XML文件編碼這種數據存儲方式是默認站點導航被硬編碼使用然而ASPNET 的提供者模型可以使你更容易地使用你自己的數據存儲來實現站點導航例如在一個我當前開發的工程中使用的一個數據庫包含站點中的頁面信息以及不同的用戶擁有頁面中什麼樣的許可權不是在一個XML文件中重新定義這些信息並且必須努力保持兩份信息的及時更新而是通過利用ASPNET 中的站點導航功能我可以簡單地創建一個提供者類它能夠直接與數據庫信息工作一旦創建這個類並且在網站的配置中指定導航Web控件就可以根據存儲在數據庫中的應用程序的定制導航信息進行工作(注意在本文成文之時這個工程使用的仍然是ASPNET x然而這個例子卻有希望能夠向你展示提供者模型的優點)
  
    作為個人我想提供者模型只是ASPNET 提供的最優秀的遷移特征之一ASPNET 提供了很多開發者在x版本中必須定制的新特征如果這些版本的新特征使用過於僵硬的實現方式那麼它將阻止基於定制方案的正在使用中的x應用程序向它的遷移因為許多新的ASPNET Web控件都使用了這些新的子系統然而有了提供者模型後我們就可以把我們的x應用程序升級到版本並且創建一個提供者以便使版本的新的子系統與我們的定制方案集成到一起這意味著當遷移到版本時我們可以使用新的Web控件並且使它們通過提供者模型而自然地使用我們的現有系統
  
補充信息
  
    隨著提供者模型成為ASPNET 中的一個重要組成部分微軟出版了很多關於這個主題的文章如果你想了解更多這方面的信息那麼我鼓勵你閱讀一下Rob Howard的兩篇文章
  
    · 《提供者模型設計模式與規范》
  
    · 《ASPNET x提供者模型》
   
    其中第二篇文章分析了如何把提供者模型應用於你的ASPNET x應用程序還有兩篇文章討論了ASPNET 的站點導航子系統中的提供者用法
  
    · 《理解和擴展ASPNET 中的站點導航系統》作者David Gristwood
  
    · 《定制ASPNET 中的提供者》作者Morgan Skinner
  
    注意微軟還發行了另外一個提供者開發工具包它也用於創建ASPNET 提供者而且還有一篇不錯的文章《ASPNET 提供者模型》可供你參考
  
結論
  
    當創建具有各種要求的大量客戶所使用的系統時一種僵硬的API實現可能會嚇壞了開發者這種僵硬的實現往往會強迫客戶同意且被鎖定於系統架構師的視野之內而一般地公司往往更對能夠與他們的現有方案協同工作的應用程序和框架感興趣而不是強迫他們的方案服從供應商提供的系統
  
    提供者模型提供了一種打破這種僵硬的實現問題的方法借助於提供者模型系統就能夠靈活地使用擴展特定基類的任何類這樣以來客戶可以創建他們自己的包括他們的定制邏輯和業務規則的派生類而且這些新類可以無縫地插接到系統中而不必干擾應用程序中的現有代碼或任何自創建以來的新的定制代碼
  
    總之提供者模型在ASPNET 中得到普通使用而且這些概念也可以應用於ASPNET x應用程序中


From:http://tw.wingwit.com/Article/program/net/201311/11957.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.