2009-06-11 50 views
4

CarTrackr project中,它使用了一些技術,爲Asp.net Mvc網站中的所有請求僅創建一個存儲庫實例,並使用UnityControllerFactory類來管理所有存儲庫實例(發送到請求的控制器)。爲Asp.net Mvc應用程序使用單個Repository實例有什麼好處嗎?

與每個請求創建新存儲庫實例相比,使用單個存儲庫實例有什麼好處嗎?

我知道,它可能會提高整體性能。但是,它會導致任何傳送問題?

局部的Global.asax

public class MvcApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     RegisterRoutes(RouteTable.Routes); 
     RegisterDependencies(); 
    } 

    protected static void RegisterDependencies() { 
     IUnityContainer container = new UnityContainer(); 

     // Registrations 
     container.RegisterType<IUserRepository, UserRepository>(new ContextLifetimeManager<IUserRepository>()); 
     container.RegisterType<ICarRepository, CarRepository>(new ContextLifetimeManager<ICarRepository>()); 

     // Set controller factory 
     ControllerBuilder.Current.SetControllerFactory(
      new UnityControllerFactory(container)  
     ); 
    } 
} 

局部CarController.cs

[Authorize] 
public class CarController : Controller 
{ 
    private IUserRepository UserRepository; 
    private ICarRepository CarRepository; 

    public CarController(IUserRepository userRepository, ICarRepository carRepository) 
    { 
     UserRepository = userRepository; 
     CarRepository = carRepository; 
    } 
} 

謝謝,

+0

(回覆評論) – 2009-06-20 19:23:00

回答

2

我認爲你誤解了ContextLifeTimeManager發生了什麼。通過將管理器傳遞給Register()方法,告訴Unity將您的存儲庫實例的緩存範圍設置爲HttpContext。

它實際上是不正確的說:

它使用一些技術,在Asp.net的所有請求創建只有1庫實例> MVC站點

沒有一個倉庫單。 Unity正在爲創建一個請求。聽起來這實際上是你想要的行爲。

當管理器的作用域設置爲HttpContext時,容器將查找HttpContext以獲取請求類型(在本例中爲您的存儲庫)的現有實例。由於HttpContext在每個請求中都是新鮮的,容器將不會有此實例,因此將創建一個新實例。

當你問:

是否有當 創建新庫實例的每個 要求比較使用單 庫實例的任何好處?

至於交易的問題:線程將DEF是一個問題。 CarRepository似乎在使用Linq2Sql或Linq2Entities。它的ctor需要一個活動的數據上下文。 DataContext不是線程安全的。如果datacontext存儲在高於當前請求的範圍內,則會出現問題。

0

使用新ContextLifetimeManager());,壽命一個存儲庫僅限於一個請求。這意味着evry會在每個存儲庫實例化(如果需要的話)之後請求響應並將其銷燬。

+0

DefaultControllerFactory和ContextLifetimeManager有什麼不同?因爲他們都會在用戶請求時創建新的Controller實例。 – 2009-06-17 23:20:05

+0

工廠是利用容器的東西。也就是說,它負責調用container.Resolve()來獲取基於配置的IController的新實例。 ContextLifetimeManager設置實例將被緩存的範圍。緩存實例使得容器不會重新創建對象,只要實例存在於作用域中即可。 – 2009-06-21 04:44:57

3

每個請求創建一個存儲庫實例本身不應該導致任何性能問題;存儲庫通常非常淺薄,當它需要訪問數據時,連接池就會減少建立實際連接的成本。對象的創建非常便宜,特別是對於像「網絡請求」這樣的短時間內容,在「零時代」仍然收集對象的情況下。

至於是否有一個單一的儲存庫或每實例庫 - 依賴於存儲庫;-p

最大的問題是:是你的資料庫線程安全的?如果沒有:每個請求一個。

即使它是;如果您的存儲庫本身保持類似於LINQ-to-SQL DataContext(您以某種方式同步),那麼如果長期保持這種狀態,特別是使用身份管理器,則會遇到很大問題。你會很快使用大量的內存得到陳舊的結果。遠非理想。

對於單個存儲庫實例,您可能最終會遇到大量阻止嘗試獲得線程安全性的阻塞。這可以通過減少的吞吐量。相反,數據庫本身有很好的實現細粒度鎖定的方法 - 當你經常考慮併發請求時,會發現併發請求會在單獨的表中等等 - 所以在數據庫層沒有阻塞。這將是非常難只是在存儲庫層 - 所以你可能不得不同步整個「獲取」 - 非常糟糕。

國際海事組織,每個請求一個在大多數情況下罰款。如果要緩存數據,請單獨執行 - 即不在存儲庫實例上直接使用

+0

在我的例子中,Can CLR可以同時調用存儲庫實例的相同方法(來自差異請求)?接下來,通過ContextLifetimeManager創建每個Web請求的實例和通過Asp.net Mvc框架創建實例有什麼區別? – 2009-06-20 16:41:44

相關問題