2011-10-13 51 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"]; 

     } 

    } 
} 
相关问题