[英]ServiceStack self-hosted application with per-request lifetime scope
Working with ServiceStack I've stuck with the problem of objects lifetime management in self-hosted web application. 使用ServiceStack我一直坚持自托管Web应用程序中对象生存期管理的问题。
My requirements: 我的要求:
General problem: 一般问题:
Castle Windsor IoC implements its own per-request lifetime strategy but it is binded to http modules, thus it works only with IIS hosted apps. Castle Windsor IoC实现了自己的每个请求生命周期策略,但它绑定到http模块,因此它仅适用于IIS托管应用程序。 Hence, I have to implement my custom IScopeAccessor (provided by Castle Windsor) to handle objects lifetime. 因此,我必须实现我的自定义IScopeAccessor(由Castle Windsor提供)来处理对象的生命周期。 The problem here is in absence of hooks which I can use to bind to current request. 这里的问题是没有钩子,我可以用它来绑定当前的请求。
Given 特定
public class MyScopeAccessor : IScopeAccessor
{
public ILifetimeScope GetScope(CreationContext context)
{
//implement it
}
}
I have to implement GetScope method. 我必须实现GetScope方法。
There are two main ideas I cannot complete: 我无法完成两个主要想法:
Using of [Threadstatic] 使用[Threadstatic]
In MyScopeAccessor I just store 在MyScopeAccessor中,我只是存储
[ThreadStatic]
private static ILifetimeScope _currentLifetimeScope;
and create new scope after first GetScope if it's not initialzied yet. 如果尚未初始化,请在第一个GetScope之后创建新范围。
Problems: 问题:
Using of IRequest instance 使用IRequest实例
In MyScopeAccessor I just store 在MyScopeAccessor中,我只是存储
private static readonly ConcurrentDictionary<IRequest, ILifetimeScope> LifetimeScopes;
and create and dispose current lifetime scope in corresponding custom ServiceRunner methods (OnBeforeEachRequest, OnAfterEachRequest). 并在相应的自定义ServiceRunner方法(OnBeforeEachRequest,OnAfterEachRequest)中创建和处置当前生命周期范围。
Problems: 问题:
Also, it is interesting if ServiceStack default Funq IoC solves this problem. 此外,有趣的是ServiceStack默认Funq IoC解决了这个问题。
Funq does handle RequestScoped dependencies which stores Request Context dependencies in the RequestContext.Instance.Items[]
dictionary. Funq确实处理RequestScoped依赖项 ,它在RequestContext.Instance.Items[]
字典中存储请求上下文依赖项。
Any disposables can be registered in RequestContext.Instance.TrackDisposable()
are automatically disposed of at the end of the request. 任何一次性用品都可以在RequestContext.Instance.TrackDisposable()
中注册, RequestContext.Instance.TrackDisposable()
在RequestContext.Instance.TrackDisposable()
结束时自动处理。
At the end of each request AppHost.OnEndRequest()
is fired which goes through and releases any dependencies stored in the RequestContext for that request. 在每个请求结束时,会触发AppHost.OnEndRequest()
,它会通过并释放存储在AppHost.OnEndRequest()
中的该请求的所有依赖项。
If your Windsor ContainerAdapter implements the IRelease
interface it's automatically called to release any instances which can be handled itself. 如果您的Windsor ContainerAdapter实现了IRelease
接口,它会自动调用以释放任何可以自行处理的实例。 Both these API's are overridable in your AppHost
if you want to change the default behavior: 如果要更改默认行为,这两个API都可以在AppHost
:
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*/ }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.