Использование ASP.NET Session для управления временем жизни (Unity) - PullRequest
17 голосов
/ 02 апреля 2009

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

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

Ответы [ 7 ]

15 голосов
/ 29 июля 2010

Вы получите лучший результат с 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 голосов
/ 23 мая 2009

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

    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, так и в Интернете

0 голосов
/ 03 августа 2010

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

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

0 голосов
/ 02 августа 2010

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

PostSharp является отличным AoP-фреймворком ИМХО.

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

0 голосов
/ 17 мая 2010

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

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

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

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

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

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

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

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

0 голосов
/ 16 мая 2009

Похоже, на самом деле вам нужен шаблон реестра, а не Unity.

http://martinfowler.com/eaaCatalog/registry.html

0 голосов
/ 02 апреля 2009

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

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

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

...