使用 ServiceStack 我一直在解决自托管 Web 应用程序中对象生命周期管理的问题。
我的要求:
- 需要每个请求对象的生命周期范围。
- 我正在使用 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 解决了这个问题,也很有趣。