Удаление вызовов сеанса ASP.net из бизнес-логики

Я унаследовал веб-решение asp.net, которое имеет бизнес-логику и вызовы данных в виде отдельных сборок. На бизнес-уровне существует небольшое количество вызовов для получения / установки значений сеанса HttpContext. Я поискал пример, который позволил бы мне абстрагироваться от бизнес-логики, поскольку я хотел бы иметь возможность повторно использовать эти сборки в не-веб-проектах, может ли кто-нибудь дать мне пример наилучшего способа сделай это. Я думал о какой-то фабрике сеансов, которая будет получать значения из какого-то постоянного хранилища в зависимости от сценария использования, но я действительно новичок в архитектуре и был бы признателен за указатель или два.


person Matt Rowett    schedule 04.02.2011    source источник
comment
Какие типы значений хранятся в состоянии сеанса?   -  person Fredrik Mörk    schedule 04.02.2011
comment
Прямо сейчас просто сложный тип, содержащий сведения о пользователях и их разрешениях на данные в виде списка Guid.   -  person Matt Rowett    schedule 04.02.2011


Ответы (3)


Какой бизнес у бизнес-уровня с Session? Чтобы лучше понять это утверждение, подумайте об этом так: зачем на бизнес-уровне когда-либо сохранять информацию, связанную с пользователем?

Бизнес-уровень должен работать и обрабатывать данные, связанные с пользователем, но не хранить их. Это означает, что данные, которые в настоящее время хранятся, должны быть введены, то есть они должны быть переданы в качестве параметра функциям, которым они нужны. Поступая таким образом, вы формируете архитектурный контракт, в котором очень явным образом говорится: «Эй, мне нужна эта информация о пользователе для выполнения моей работы» - вы не совершаете магию под капотом с некоторыми случайными ранее сохраненными значениями. Для бизнес-уровня нормально аутентифицировать или авторизовать пользователя каким-либо образом с использованием этих данных, но он должен отбросить результаты аутентификации после того, как он закончил с ними. Если значения сохраняются для сохранения одного или двух вызовов в базе данных, тогда у вас есть проблема с эффективностью вызовов базы данных, потому что база данных вызывает простые вещи, подобные этому, быстро.

Поэтому я предлагаю удалить все ссылки на сеанс с вашего бизнес-уровня и изменить сигнатуры ваших функций, чтобы они включали в себя передаваемые вами пользовательские данные.

person slugster    schedule 04.02.2011
comment
Поразмыслив, вы правы, я не хочу хранить значения в этом слое, я просто хочу, чтобы этот слой мог использовать данные, которые в настоящее время сохраняются в сеансе. В этом случае список Guid, хранящийся в Session, напрямую отражается в базе данных, поэтому при необходимости я могу получить его оттуда. Я предполагаю, что на самом деле я хотел передать запрос этих данных третьей стороне (фабрике сеансов), которая вернет мне список из наиболее подходящего места, которое, как я думаю, будет сеансом при вызове из пользовательского интерфейса и базы данных, если нет. - person Matt Rowett; 04.02.2011
comment
Потрясающе ... Я не против голосов против, где это оправдано, но мне бы очень хотелось, чтобы человек, проголосовавший против этого, рассказал о своих ошибках. Я не пропускаю двух повторений, это просто вопрос принципа. - person slugster; 09.02.2011

На мой взгляд, самый простой способ - создать ISessionProvider интерфейс с Dictionary<string, object> {get; }. Затем создайте public class HttpSessionProvider : ISessionProvider, который возвращает фактическое содержимое пакета сеанса.

По крайней мере, создайте экземпляр этого объекта в своем веб-приложении и передайте его бэкэнд-классу, указав его вручную или используя любой шаблон IOC.

[Edit] после небольшого размышления, это не чистый способ. У вас не будет зависимости от фреймворка asp.net, но вы все равно будете иметь доступ к содержимому asp.net сеанса. В этом случае оставьте интерфейс, но либо добавьте определенные свойства (string customer, int userID и т. Д.), Либо верните словарь только с фактическими бизнес-данными.

person Steve B    schedule 04.02.2011

Я делал что-то подобное в некоторых проектах:

public interface IAppContext {
    string SomeVariable {
        set;
        get;
    }
}
public class HttpContextAppContext : IAppContext {

    public static readonly string CONTEXT_PREFIX = "appcontext_";

    public string SomeVariable {
        set { HttpContext.Current.Session[CONTEXT_PREFIX + "SomeVariable"] = value; }
        get { return (string)HttpContext.Current.Session[CONTEXT_PREFIX + "SomeVariable"]; }
    }
}
person djeeg    schedule 04.02.2011