2011-10-13 50 views
0

因此,我從另一個開發人員手中接管了一個VB.net Web應用程序項目,並發現了迄今爲止編寫的代碼的一個明顯問題。將一個ASP.net Singleton會話實例轉換爲一個對象

開發人員已經構建了基於本教程的購物車應用程序(http://net.tutsplus.com/tutorials/other/build-a-shopping-cart-in-aspnet/)。

注意:要使用這個作爲一個生產ASP.net購物車的基礎上考慮任何開發人員 - 不 - 閱讀,以瞭解更多....

誰寫的教程中實現過的人最近使用Singleton對於基於會話的購物車來說不是一個非常聰明的模式。事實上,它是愚蠢的 - 真的很愚蠢。有了這種模式,每個用戶都有相同的購物車實例!

本教程中有許多有用的評論,關於如何將Singleton實例會話轉換爲對象(如作者:http://net.tutsplus.com/tutorials/other/build-a-shopping-cart-in-aspnet/comment-page-1/#comment-56782)。

但我的應用程序使用VB.net當量(在該網頁上下載文件提供),什麼我不知道是我將需要經過整個應用程序,並轉移到的所有喜歡引用:

ShoppingCart.Instance.AddItem 

手動喜歡的東西代替它們:

Dim cart As ShoppingCart = ShoppingCart.GetShoppingCart() 

cart.AddItem(3)

或者是有什麼聰明的我可以做CONVER t此代碼:

#Region "Singleton Implementation" 

' Readonly variables can only be set in initialization or in a constructor 
Public Shared ReadOnly Instance As ShoppingCart 
' The static constructor is called as soon as the class is loaded into memory 
Shared Sub New() 
    ' If the cart is not in the session, create one and put it there 
    ' Otherwise, get it from the session 
    If HttpContext.Current.Session("ASPNETShoppingCart") Is Nothing Then 
     Instance = New ShoppingCart() 
     Instance.Items = New List(Of CartItem) 
     HttpContext.Current.Session("ASPNETShoppingCart") = Instance 
    Else 
     Instance = CType(HttpContext.Current.Session("ASPNETShoppingCart"), ShoppingCart) 
    End If 

到其他東西,所以我不需要更改實例調用?

例如像這樣的東西(這是我在文章的另一個評論中發現的C#代碼片段 - 我需要一個VB.net等價物,但我不確定如何編寫它 - 我的VB.net有點生疏!)

public static ShoppingCart Instance 
{ 
    get 
    { 
     ShoppingCart c=null; 
     if (HttpContext.Current.Session["ASPNETShoppingCart"] == null) 
     { 
      c = new ShoppingCart(); 
      c.Items = new List(); 
      HttpContext.Current.Session.Add(「ASPNETShoppingCart」, c); 
     } 
     else 
     { 
      c = (ShoppingCart)HttpContext.Current.Session["ASPNETShoppingCart"]; 
     } 
     return c; 
    } 
} 

感謝您提供任何幫助。

埃德

+0

哪些存儲選項?這是全部在內存中,還是由SQL等支持...? – bryanmac

+0

@bryanmac足夠公平:)我不故意不接受答案。 –

+0

@bryanmac - 我卡與INPROC(內存) - 我有一個CMS僅支持INPROC(它不能序列顯然會話數據)約.Instance沒有改變 –

回答

0

編輯:

你並不需要改變,如果你做上面的代碼的實例調用。在大多數實例調用中,它們會創建靜態對象(如果爲null)並將其填充到靜態成員變量中,並繼續將同一個對象移出(可能會使用一些雙重鎖定檢查)。在上面的代碼中,你不這樣做 - 你轉過身來發出會話狀態字典中的一個,這樣每個會得到一個不同的。

在這種情況下,術語實例會有點誤導,但您不必更改所有調用代碼。從邏輯上講,它將是他們購物車的一個實例。

...

使用HttpContext.Current.Session詞典可以讓你一車存放在每個購物用戶內存。

在內存中的會話的缺點是,如果IIS應用程序池回收,它將會消失。另外,如果您需要添加其他Web服務器(擴展),則需要使用NLB關聯 - 它僅限制您的選項。你的記憶也會增長,因爲他們的購物車在會話的整個一生中都會留在記憶中 - 但這對於購物網站來說是一個很好的問題:)但是,它簡單而輕便。

其他選項將在DB或者存儲會話狀態通過配置或推出自己的購物車表。

另一個選擇是使用雲存儲 - 像Azure的餐桌服務。你得到兩全其美 - 你們不必保留您的SQL服務器,你會得到跨越再循環等冗餘性和耐久性......哎 - 你可以在同一時間與新技術玩:)

+0

加點。 – bryanmac

+0

完美@bryanmac - 看到我確實接受的答案 - 當他們和你一樣好:) –

+0

:) Thx - 我通常回答,但我戳希望能幫助人。有些人不知道.. – bryanmac

0

使用此代碼

公共靜態實例的ShoppingCart { 得到 {

 if (HttpContext.Current.Session["ASPNETShoppingCart"] == null) 
     { 

      // we are creating a local variable and thus 

      // not interfering with other users sessions 

      ShoppingCart instance = new ShoppingCart(); 

      instance.Items = new List<CartItem>(); 

      HttpContext.Current.Session["ASPNETShoppingCart"] = instance; 

      return instance; 

     } 
     else 
     { 

      // we are returning the shopping cart for the given user 

      return (ShoppingCart)HttpContext.Current.Session["ASPNETShoppingCart"]; 

     } 

    } 
} 
相關問題