Подтвердить что ты не робот

Использование сеанса ASP.NET для управления жизненным циклом (Unity)

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

До сих пор мое лучшее решение - создать статический экземпляр контейнера Unity при запуске и использовать метод Resolve для получения объекта User из каждого из моих классов. Однако, похоже, это создает зависимость от контейнера единства в моих других классах. Чем больше "Единство" способ достижения этой цели? Я хотел бы иметь возможность читать/заменять текущий экземпляр пользователя из любого класса.

4b9b3361

Ответ 1

Вы получите лучший удар с Unity при использовании с ASP.Net MVC, а не простой старый проект ASP.Net. ASP.Net MVC позволяет использовать такой контейнер, как Unity, для управления объектами пользователей, контроллерами, моделями и т.д. Если возможно, используйте MVC, а не веб-формы ASP.net для ваших проектов.

Если я правильно понял ваш вопрос, вы бы хотели использовать Unity для поддержания времени жизни объекта за сеанс. Вам необходимо реализовать SessionLifetimeManager, который расширяет LifetimeManager. Код довольно прост и идет по этим строкам:

public class SessionLifetimeManager : LifetimeManager
{
    private string _key = Guid.NewGuid().ToString();

    public override object GetValue()
    {
          return HttpContext.Current.Session[_key];
    }

    public override void SetValue(object value)
    {
          HttpContext.Current.Session[_key] = value;
    }

    public override void RemoveValue()
    {
          HttpContext.Current.Session.Remove(_key);
    }
}

Вы также можете написать аналогичный для управления жизненным циклом PerWebRequest.

Ответ 2

Почему бы не использовать объект кэша вместо этого... тогда вы можете использовать его как от win, так и от сети. Вот так:

    IUnityContainer container= HttpRuntime.Cache.Get("Unity") as IUnityContainer;

    if (container == null)
    {
        container= // init container

        HttpRuntime.Cache.Add("Unity",
            container,
            null,
            Cache.NoAbsoluteExpiration,
            Cache.NoSlidingExpiration,
            CacheItemPriority.NotRemovable,
            null);
    }

    // return container or something

HttpRuntime.Cache будет работать как в win, так и в Интернете

Ответ 3

Я бы подумал, что вам нужны две службы, которые вы открываете через единицу (или одну службу, которая выполняет оба действия).

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

У вас также будет установлен метод/свойство set, который вы бы использовали для установки пользователя.

Ответ 5

Возможно, я передумал, но я думаю, что вы должны использовать AoP вместе с IoC. Это действительно красивое спаривание. По сути дела, что я хотел бы сделать, это захватить конструктор классов, которые вы разрешаете, иначе называете создание аспект. Затем вы можете ввести пользователя в класс при входе в конструктор, но все, что разрешает класс, явно не должно предоставлять пользователю, тем самым предотвращая сопряжение с самим Unity.

PostSharp - отличная инфраструктура AoP IMHO.

Теперь в конечном итоге ваше приложение будет зависеть от структуры AoP, но полностью развязанное приложение может быть нереалистичным в зависимости от вашей среды. Вы можете быть удивлены, насколько полезной может быть комбинация AoP и IoC.

Ответ 6

Если с помощью "пользовательского диспетчера сеансов ASP.NET" вы говорите о сеансе NHibernate или Data/ObjectContext, это звучит так, как вам нужно, это IUserRepository, введенный либо в конструктор, либо с помощью средства настройки свойств, из которого вы можете получить Пользовательский объект. Реализация IUserRepository может быть чем угодно: от доступа к базе данных до бэкэнд-кэша и т.д. Если вы используете Rewolve() непосредственно в контейнере, вы следуете Service Locator и не правильно использовать Unity для всего, что он может предоставить.

Затем вы можете использовать ответ Ravi для управления временем жизни репозитория.

Ответ 7

Мои извинения, если это не совсем правильно, но...

Unity - это игровая платформа, поэтому я предполагаю, что вы создаете 3D-приложение или игру, которые вы намереваетесь делать с чем-то классным (например, заставляйте его многопользовательский/отслеживать прогресс пользователей с помощью сервера).

Почему бы не войти в каждый пользователь, тогда вы можете использовать классы MembershipProvider и Formsauthentication, чтобы получить доступ к идентификатору/имени пользователя.

На вашем сервере вы просто связываете всю информацию с информацией для пользователя, которая позволяет вам легко отбрасывать данные (простые данные ajax/normal http), относящиеся к ситуации/запросу пользователей.

Я не знаю этого точно, но я считаю, что единство - это то, что развертывает клиентскую сторону, поэтому на нем не нужно интегрироваться с ним.

Просто спросите, что вам нужно, и обработайте его на стороне клиента.

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

Надеюсь, что это поможет...