Преобразовать экземпляр сеанса ASP.net Singleton в объект - PullRequest
0 голосов
/ 14 октября 2011

Итак, я взял на себя проект веб-приложения VB.net от другого разработчика и обнаружил явную проблему с кодом, написанным на сегодняшний день.

Разработчик создал приложение для корзины покупок на основе этого руководства(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)

Или есть что-то умнееЯ могу сделать, чтобы преобразовать этот код:

#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 # Iнашел в другом комментарии в статье - мне нужен 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;
    }
}

Спасибо за любыепомощь, которую вы можете предоставить.

Ed

Ответы [ 2 ]

0 голосов
/ 09 февраля 2015

Используя этот код

public static ShoppingCart Instance {get {

        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"];

        }

    }
}
0 голосов
/ 14 октября 2011

EDIT:

Вам не нужно менять вызовы экземпляра, если вы делаете код выше. В большинстве вызовов экземпляров они создают статический объект, если он равен нулю, и помещают его в статическую переменную-член и продолжают выдавать тот же объект (возможно, с некоторыми проверками двойной блокировки). В приведенном выше коде вы этого не делаете - вы поворачиваетесь и выдаете один из них в свой словарь состояний сеанса, чтобы каждый из них получал по-своему.

Термин экземпляр в этом случае будет немного ошибочным, но вам не нужно менять весь вызывающий код. Логически это будет экземпляр их корзины.

...

Использование словаря HttpContext.Current.Session позволит вам хранить корзину в памяти для каждого покупателя.

Недостаток сеанса в памяти - если пул приложений IIS перезагружается, он исчезнет. Кроме того, если вам когда-нибудь понадобится добавить другой веб-сервер (масштабировать), вам нужно будет использовать сходство NLB - это просто ограничивает ваши возможности. Ваша память также растет, так как их корзина останется в памяти на всю жизнь сеанса - но это хорошая проблема для магазина покупок :) Но он очень простой и легкий.

Другими вариантами может быть сохранение состояния сеанса в БД через конфигурацию или создание собственных таблиц корзины покупок.

Еще одним вариантом будет использование облачного хранилища - что-то вроде табличных служб Azure. Таким образом, вы получаете лучшее из обоих миров - вам не нужно обслуживать свой SQL-сервер, вы получаете избыточность и долговечность на всех этапах переработки и т. Д. И, эй, - вы можете играть с новой технологией одновременно:)

...