我犯了一个错误,您能指出吗?
這是我最近在項目中犯的一個錯誤,您能指出嗎?
這個項目在數據訪問方面使用了傳統的Repository模式。為此,我定義了一個Repository基類,可以讓每個不同的Repository繼承它:
public abstract class Repository<T> { ... }public class UserRepository : Repository<User> { ... }public class ArticleRepository : Repository<Article> { ... }Repository類中提供了一些基礎功能,可以讓各個不同的Repository子類復用,這是十分常見的做法。其中一個功能便是資源的管理。在項目中,資源的管理通過Resource Manager進行——這不是.NET框架中自帶的ResourceManager類,而是自己定義的組件:
public abstract class Repository<T> {private IResourceManager ResourceManager { get { ... } } }public interface IResourceManager {void Set(object key, object value);T Get<T>(object key); }被Resource Manager管理的資源會在一定時刻統一釋放,而不同的IResourceManager對象的實現也有不同的“作用域”。例如,在Web項目中常見的做法是,對于每個數據庫來說,每個請求使用一個連接。因此,這里使用的可能就是RequestResourceManager,它基于HttpReuqest提供資源存儲,保證資源的作用域是當前請求。
數據庫連接也是需要管理的資源之一,因此我在Repository中定義了一個GetConnection方法(假設只需要連接一個數據庫):
public abstract class Repository<T> {private readonly static Guid ConnectionKey = Guid.NewGuid();protected IDbConnection GetConnection(){var conn = this.ResourceManager.Get<IDbConnection>(ConnectionKey);if (conn == null){conn = new SqlConnection("...");this.ResourceManager.Set(ConnectionKey, conn);}return conn;} }我在Repository類中定義了一個全局的ConnectionKey靜態字段,并且在初始化時給它指定一個新的GUID。這個字段是readonly的,因此除非應用程序重啟,ConnectionKey的值不會改變。而在GetConnection方法中,我把ConnectionKey作為標識,向Resource Manager中獲取資源。從GetConnection方法的實現中可以看出,由于我們使用了RequestResourceManager,因此如果是同一個請求的話,就會共享相同的數據庫連接對象。
于是,我們的代碼里就可以這么寫:
public void DoSomething() {var userRepository = new UserRepository();// 使用userRepositoryvar articleRepository = new ArticleRepository();// 使用articleRepository }在使用userRepository的時候,ResourceManager里還沒有數據庫連接,因此UserRepository會創建一個新的Connection對象。而在使用articleRepository的時候,它會發現ResouceManager中已經存在一個Connection對象了,于是便可取出繼續使用。而這個連接會在請求結束時自動釋放。
這就是我這個設計的目的。但是,在實現的過程中我犯了一個嚴重的錯誤,您發現了嗎?(結論)
from:?http://blog.zhaojie.me/2009/09/i-made-a-mistake-can-you-figure-it-out.html
總結
以上是生活随笔為你收集整理的我犯了一个错误,您能指出吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 您能看出这个Double Check里的
- 下一篇: 我犯了一个错误,您能指出吗?(结论)