C# 具有每个请求生存期作用域的ServiceStack自托管应用程序
使用ServiceStack时,我一直在解决自托管web应用程序中的对象生命周期管理问题 我的要求:C# 具有每个请求生存期作用域的ServiceStack自托管应用程序,c#,
servicestack,castle-windsor,ioc-container,lifetime-scoping,C#,
servicestack,Castle Windsor,Ioc Container,Lifetime Scoping,使用ServiceStack时,我一直在解决自托管web应用程序中的对象生命周期管理问题 我的要求: 需要每个请求对象的生存期范围 我正在使用Castle Windsor IoC和已实现的ServiceStack IoC适配器 我的应用程序是使用基类AppHostHttpListenerPoolBase(ServiceStack v4)自托管的 也许有一天我想在IIS上移动,所以它必须是灵活的 一般问题: Castle Windsor IoC实现了自己的每请求生存期策略,但它绑定到http模块,
公共类MyScopeAccessor:IScopeAccessor
{
公共ILifetimeScope GetScope(CreationContext上下文)
{
//实施它
}
}
我必须实现GetScope方法
有两个主要想法我无法完成:
使用[Threadstatic]
在MyScopeAccessor中,我只存储
[ThreadStatic]
专用静态ILifetimeScope\u currentLifetimeScope;
并在第一个GetScope之后创建新的作用域(如果尚未初始化)
问题:
私有静态只读ConcurrentDictionary生存时间范围;
并在相应的自定义ServiceRunner方法(OnBeforeAchRequest、OnAfterEachRequest)中创建和处理当前生存期范围
问题:
RequestContext.Instance.Items[]字典中存储请求上下文依赖项的操作
可以在RequestContext中注册任何可处置项。Instance.TrackDisposable()
将在请求结束时自动处置
在每个请求结束时,都会触发AppHost.OnEndRequest()
,该请求会遍历并释放该请求的RequestContext中存储的任何依赖项
如果您的Windsor ContainerAdapter实现了IRelease
接口,则会自动调用该接口以释放任何可自行处理的实例。如果要更改默认行为,则可在AppHost
中重写这两个API:
public virtual void OnEndRequest()
{
var disposables = RequestContext.Instance.Items.Values;
foreach (var item in disposables)
{
Release(item);
}
RequestContext.Instance.EndRequest();
}
public virtual void Release(object instance)
{
try
{
var iocAdapterReleases = Container.Adapter as IRelease;
if (iocAdapterReleases != null)
{
iocAdapterReleases.Release(instance);
}
else
{
var disposable = instance as IDisposable;
if (disposable != null)
disposable.Dispose();
}
}
catch { /*ignore*/ }
}
谢谢现在很清楚Funq是如何工作的。但主要问题是如何从任意代码位置(包括MyScopeAccessor)映射到当前请求上下文。有了这个能力,我可以做任何事情,也可以处理。另外,我不想实现已经实现的温莎城堡的一部分。我认为RequestContext.Instance.Items是请求上下文标识的最佳选择,对吗?也就是像使用静态ConcurrentDictionary LifetimeScopes一样使用它以RequestContext.Instance.Items对象作为键。并且不符合
RequestContext.Instance
的要求,因为它似乎是一个单例?@ValentinP.RequestContext.Instance
是一个单例,您可以使用RequestContext.Instance.Items
对象字典来保存请求范围的依赖项来标识请求。默认情况下,幕后Items
使用HttpContext.Current.Items
(ASP.NET)或CallContext.LogicalData
进行自我托管,否则RequestContext.RequestItems
如果RequestContext.UseThreadStatic=true
。有关详细信息,请参阅impl。