2011-04-10 93 views
1

我剛剛發現的擴展方法,我愛他們這麼多,我很害怕他們用好...靜態業務層和擴展方法

我有一個3層的ASP網應用。我DAL是基於實體框架,我的用戶界面是這樣的實體查詢aspx頁面和我的商業邏輯用來作爲公用類使用LINQ:

public List<Site> GetAll() 
{ 
    return db.Sites.Include(s=> s.City).ToList(); 
} 

,你需要實例化和使用這樣的:

CSite objsite = new CSite(); 
List<Site> sites = objsite.GetAll(); 

後來我發現IQueryable的,所以這樣我可以「再利用」我的查詢是這樣的:

public ObjectQuery<Site> GetAll() 
{ 
    return db.Sites.Include(s=> s.City); 
} 

public IQueryable<Site> Filter(IQueryable<Site> query, string filterWord) 
{ 
    return (from s in query 
      s.Name.Contains(word) 
      select s); 
} 

List<Site> sites = objsite.Filter(objsite.GetAll(),"filter word").ToList(); 

過濾器()方法只適用於GETALL where子句()IQueryable的和THI s是真棒,直到我發現擴展方法,所以我能應付這樣的:

public static IQueryable<Site> Filter(this IQueryable<Site> query, string word) 
{ 
     return (from s in query 
      s.Name.Contains(word) 
      select s); 
} 

而這甚至更好,因爲現在我有這樣的智能感知我的疑問:

List<Site> sites = objsite.GetAll().Filter("filter word").ToList(); 

現在,這在這裏我很害怕,是因爲三件事情的一部分:

  1. 你認爲這是一個很好的方法來N層應用程序?這是一個很好的設計模式,或者只是一個懶惰的解決方案嗎?

  2. 鑑於擴展方法需要靜態方法下的靜態方法,我的業務層將全部是靜態的,這是一個好方法嗎?是否應該將非擴展方法放在相同的靜態類下? (例如GetAll()或AddNew())

  3. 作爲Asp Net應用程序是否有所有這些靜態的東西?

非常感謝你們!

回答

2

IQueryable之上使用自定義擴展方法很常見。我認爲這是重用查詢部件的好方法。應謹慎使用擴展方法。擴展方法只是靜態方法中的句法糖。我的朋友有關於他的collegue一個很好的故事,誰最近發現的擴展方法,並開始使用如下代碼:

var order = 1.GetOrder(); // Extension on integer - this is really bad example 

的問題在你的例子是靜態的業務層。業務層必須以某種方式接收上下文,並且必須根據請求處理上下文。 Sharing context之間的請求或單個上下文整個應用程序是有嚴重問題的最佳方式。因此,除非您將上下文傳遞給每個方法,否則您還必須爲每個請求創建業務類。

但仍然應該使用IQueryalbe的擴展名。你可能會發現你的商業類只是一個圍繞context.Query的包裝,在這種情況下,它是不需要的附加層。

另外請注意,這一切都適用於分層體系結構,但如果您的n層意味着真正的物理分離(每個層在一個單獨的服務器上),那麼它是一個不同的故事,因爲你需要的東西,可以讓你創建一個linq在一個層上查詢並在另一個層上執行(在另一個服務器上,這樣查詢和結果必須通過網絡傳輸) - 一個這樣的工具是WCF數據服務。