2012-05-03 117 views
0

我編寫了一個分層的.NET 4.0應用程序。數據層是使用實體框架實現的,並且存在將實體實例提供給調用者(即業務層)的存儲庫。當實體框架被問及某個實體兩次(例如通過鍵)時,它將返回相同的實例,所以我對實體所做的更改將反映在實體所使用的其他位置。但它並不是一個真正的緩存功能,因爲沒有過期策略,並且性能看起來沒有多大提高,因爲實體框架仍然會查詢數據庫,至少在很多情況下。重點在於確保每個實體只有一個實例(每個上下文)。在實體框架中實現「每個對象一個實例」

在業務層中,實體映射到可能與實體結構不同的業務對象。再次,像數據層中的存儲庫一樣,存在集中的訪問點來獲取業務對象的實例。我現在的目標是,具有與實體框架所提供的功能相同的功能,即在業務層中「始終爲某個對象返回相同的實例」。我想確保在應用程序的任何位置對某個業務對象的每次訪問都可以在同一個實例上運行。

BEGIN EDIT

上下文感知很重要!與實體框架類似,每個業務對象實例的唯一性應該在每個上下文基礎上提供,而不是嚴格在整個應用程序上提供。在業務層中還有上下文的概念,每個上下文應該有自己的每個業務對象的實例。這個實例應該在使用上下文的任何地方重用。

另外我正在尋找一個解決方案,不需要爲每個單一的業務對象類實現。其中可能有數百個。我更喜歡框架代碼中的解決方案,這對於實施存儲庫的人來說是儘可能透明的。實體框架本身也不知道具體的實體類型,實體框架仍然能夠爲實體模型開發人員提供透明的功能。

編輯完

我的問題是:

  • 是否有一個名字爲這個「每個對象只有一個實例」的行爲? Google搜索字詞是什麼?
  • 是否有參考文獻,指導方針或最佳實踐,或者是否存在處理此問題的設計模式?
  • .NET中是否有類有助於編寫這樣的功能,甚至完全提供它?

感謝和問候, 彼得。

回答

0

是的,它有一個名字。它被稱爲Identity Map模式,通常它只是對象鍵/對象對的字典。

+0

非常感謝您的提示!你是否知道我可以在業務層重用的(儘可能)泛型實現,還是我必須自己編寫它? – Peter

0

這裏是可以給你一個方向的樣本。想想你有類用戶(帶私人編號的setter):

public class User 
{ 
    public int Id { get; private set; } 
    public string Name { get; set; } 
} 

商店內庫中的所有用戶(我用字典,以便快速訪問):

public class UserRepository 
{ 
    private static UserRepository _instance = new UserRepository(); 
    Dictionary<int, User> _users = new Dictionary<int, User>(); 

    private UserRepository() 
    { 
    } 

    public static UserRepository Instance 
    { 
     get { return _instance; } 
    } 

    public IEnumerable<User> FindAll() 
    { 
     return _users.Values; 
    } 

    public User FindById(int id) 
    { 
     return _users[id]; 
    } 

    public void SaveOrUpdate(User user) 
    { 
     if (user.Id == 0) 
     { 
      int nextId = _users.Count + 1; 
      PropertyInfo id = typeof(User).GetProperty("Id"); 
      id.SetValue(user, nextId, null); 
      _users.Add(user.Id, user); 
      return; 
     } 

     _users[user.Id] = user; 
    } 
} 

什麼這裏有趣的是:

  • 存儲庫是單身人士。因爲您只需要一個用戶的集合/字典存在
  • 當您在程序中創建用戶時,其ID將爲0.因此您可以定義它的新用戶或其現有的用戶
  • 使用反射設置專用屬性值
  • 辛格爾頓執行情況和下一ID生成很簡單(只是簡單的例子)

現在你可以這樣做:

UserRepository repository = UserRepository.Instance; 
repository.SaveOrUpdate(new User() { Name = "Joe" }); 

而且別的地方ÿ ou可以得到相同的用戶實例:

var otherRepository = UserRepository.Instance; 
User user = otherRepository.FindById(1); 
+0

謝謝你的建議!但是,您的方法在我的方案中有兩個缺點,如果我沒有足夠清楚地表示歉意:缺乏環境意識,缺乏資源庫開發人員的透明度。我相應地提出了我的問題。可能我要求的太多了(特別是第二部分),我想象的是無法完成的,但如果你有更多的想法,我會很樂意閱讀它們! – Peter

+0

@Peter簡單的類「上下文」與你的實體的字典呢?順便說一句,沒有必要爲每個類實現存儲庫。您可以創建類似「Repository 」的通用資料庫,並將其用於任何參數:「Repository 」。 –

+0

事實上,我已經有了一個Context類,並且在那裏存儲我的業務對象已經超出了我的想法。但是:我不能簡單地使用你的通用方法。我的業務對象存儲庫需要特定的邏輯,它們必須逐個寫入(儘管它們共享一個通用的通用接口)。所以關鍵的問題是:如何讓我的存儲庫使用位於上下文中的實例高速緩存,並在每個存儲庫中儘可能少地打印(理想情況下爲零)? – Peter

相關問題