Использование сеанса ASP.NET для управления жизненным циклом (Unity)
Я рассматриваю возможность использования Unity для управления временем жизни пользовательского экземпляра пользовательского класса. Я планирую расширить LifetimeManager с помощью специального менеджера сеансов ASP.NET. Я хочу, чтобы иметь возможность хранить и извлекать текущий пользовательский объект из моих пользовательских классов, а Unity - получить экземпляр пользователя из объекта сеанса в ASP.NET или (когда в проекте Win32) получить его статически или из текущего потока.
До сих пор мое лучшее решение - создать статический экземпляр контейнера Unity при запуске и использовать метод Resolve для получения объекта User из каждого из моих классов. Однако, похоже, это создает зависимость от контейнера единства в моих других классах. Чем больше "Единство" способ достижения этой цели? Я хотел бы иметь возможность читать/заменять текущий экземпляр пользователя из любого класса.
Ответы
Ответ 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, который вы бы использовали для установки пользователя.
Ответ 4
Похоже, на самом деле вам нужен шаблон реестра, а не Unity.
http://martinfowler.com/eaaCatalog/registry.html
Ответ 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.
Надеюсь, что это поможет...