Session 将ASP.net单例会话实例转换为对象

Session 将ASP.net单例会话实例转换为对象,session,singleton,instance,Session,Singleton,Instance,因此,我从另一个开发人员那里接管了一个VB.net web应用程序项目,并发现了迄今为止编写的代码中存在的一个突出问题 开发人员基于本教程构建了一个购物车应用程序http://net.tutsplus.com/tutorials/other/build-a-shopping-cart-in-aspnet/. 注意:对于任何考虑将此作为生产ASP.net购物车基础的开发人员-不要-继续阅读了解更多 编写该教程的人意识到,对于基于会话的购物车来说,使用单例模式并不是一个非常聪明的模式,这已经太晚了。

因此,我从另一个开发人员那里接管了一个VB.net web应用程序项目,并发现了迄今为止编写的代码中存在的一个突出问题

开发人员基于本教程构建了一个购物车应用程序http://net.tutsplus.com/tutorials/other/build-a-shopping-cart-in-aspnet/.

注意:对于任何考虑将此作为生产ASP.net购物车基础的开发人员-不要-继续阅读了解更多

编写该教程的人意识到,对于基于会话的购物车来说,使用单例模式并不是一个非常聪明的模式,这已经太晚了。事实上,这很愚蠢——真的很愚蠢。使用此模式,每个用户都有相同的购物车实例

关于如何将Singleton实例会话转换为作者提供的对象,本教程中有许多有用的注释:

但我的应用程序使用了该页面下载文件中提供的VB.net等效程序,我想知道的是,我是否需要浏览整个应用程序并删除对以下内容的所有引用:

ShoppingCart.Instance.AddItem
并手动将其替换为以下内容:

Dim cart As ShoppingCart = ShoppingCart.GetShoppingCart()
cart.AddItem3

或者我可以做些更聪明的事情来转换此代码:

#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
这样我就不需要更改实例调用了

e、 这是我在文章的另一条评论中发现的一段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;
    }
}
谢谢你能提供的帮助

编辑:

如果执行上述代码,则无需更改实例调用。在大多数实例调用中,如果为null,它们会创建静态对象,并将其填充到静态成员变量中,然后通过一些双锁检查继续传递相同的对象。在上面的代码中,您不会这样做-您会转过身,在他们的会话状态字典中给出一个,这样每个人都会得到一个不同的

在这种情况下,术语instance会有一点错误,但您不必更改所有调用代码。从逻辑上讲,它将是他们的购物车的一个实例

使用HttpContext.Current.Session字典将允许您在内存中为每个购物用户存储购物车

内存会话的缺点是,如果IIS应用程序池被回收,它就会消失。此外,如果您必须添加另一个web服务器,则需要使用NLB关联-它只会限制您的选择。你的记忆也在增长,因为他们的购物车在整个会话期间都会留在内存中——但这对于购物网站来说是个好问题:但是,它非常简单,重量也很轻

其他选项是通过配置将会话状态存储在数据库中,或者滚动您自己的购物车表

另一个选择是使用云存储——类似于Azure表服务。通过这种方式,您可以两全其美—您不必维护SQL server,您可以在回收过程中获得冗余和耐久性等。。。嘿,您可以同时使用一种新技术:

使用此代码

公共静态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"];

        }

    }
}

存储选项是什么?都在内存中还是由SQL等支持?@bryanmac很公平:我不是故意不接受答案。@bryanmac-我被Inproc内存卡住了-我有一个只支持Inproc的CMS,它不能序列化会话数据显然完美@bryanmac-看我接受答案-当答案和你的一样好时::Thx-我通常会回答,但我希望能帮助人们。有些人没有意识到。。