Работая с ServiceStack, я столкнулся с проблемой управления временем жизни объектов в собственном веб-приложении.
Мои требования:
- Необходимость области действия объектов для каждого запроса.
- Я использую Castle Windsor IoC с реализованным адаптером ServiceStack IoC.
- Мое приложение размещено на собственном хосте с базовым классом AppHostHttpListenerPoolBase (ServiceStack v4)
- Вероятно, когда-нибудь я захочу перейти на IIS, поэтому он должен быть гибким.
Общая проблема:
Castle Windsor IoC реализует собственную стратегию жизненного цикла каждого запроса, но она привязана к http-модулям, поэтому работает только с приложениями, размещенными в IIS. Следовательно, я должен реализовать свой собственный IScopeAccessor (предоставленный Castle Windsor) для обработки времени жизни объектов. Проблема здесь в отсутствии хуков, которые я могу использовать для привязки к текущему запросу.
Данный
public class MyScopeAccessor : IScopeAccessor
{
public ILifetimeScope GetScope(CreationContext context)
{
//implement it
}
}
Мне нужно реализовать метод GetScope.
Есть две основные идеи, которые я не могу завершить:
Использование [Threadstatic]
В MyScopeAccessor я просто храню
[ThreadStatic]
private static ILifetimeScope _currentLifetimeScope;
и создайте новую область после первого GetScope, если она еще не инициализирована.
Проблемы:
- Трудно утилизировать. Лучший способ избавиться от _currentLifetimeScope — реализовать собственный IServiceRunner (или наследовать от ServiceRunner), переопределяющий метод AfterEachRequest. Но я точно не знаю, действительно ли AfterEachRequest выполняется в потоке запросов.
- Переход на IIS может вызвать некоторые проблемы, потому что, насколько я знаю, IIS не гарантирует неизменную привязку между объявлениями и контекстами запросов.
Использование экземпляра IRequest
В MyScopeAccessor я просто храню
private static readonly ConcurrentDictionary<IRequest, ILifetimeScope> LifetimeScopes;
а также создавать и удалять текущую область действия в соответствующих пользовательских методах ServiceRunner (OnBeforeEachRequest, OnAfterEachRequest).
Проблемы:
- Я не знаю, как получить доступ к текущему запросу глобально из GetScope, MyScopeAccessor ничего не знает о службах и запросах.
Кроме того, интересно, решает ли эту проблему ServiceStack по умолчанию Funq IoC.