“每request"激活上下文…没有要求
本文关键字:上下文 激活 request quot | 更新日期: 2023-09-27 17:54:10
我有一个需要为每个请求创建的存储库。现在有一个单例缓存对象需要使用存储库来填充数据,但是这个对象是在Application_Start事件中初始化的,因此没有请求上下文。
用Ninject实现这一点的最好方法是什么?
谢谢。
由于当前HttpContext
在应用程序启动时缺失(在IIS7集成模式下),Ninject肯定会像在InTransientScope
中一样对待对象绑定的InRequestScope
,因为当您尝试在应用程序启动时注入依赖。我们可以在Ninject(2.2)的源代码中看到:
/// <summary>
/// Scope callbacks for standard scopes.
/// </summary>
public class StandardScopeCallbacks
{
/// <summary>
/// Gets the callback for transient scope.
/// </summary>
public static readonly Func<IContext, object> Transient = ctx => null;
#if !NO_WEB
/// <summary>
/// Gets the callback for request scope.
/// </summary>
public static readonly Func<IContext, object> Request = ctx => HttpContext.Current;
#endif
}
HttpContext.Current
将在应用程序启动时为null
,因此InRequestScope
绑定对象将在应用程序启动时以与绑定InTransientScope
相同的方式处理。
你可以在你的global.asax
:
protected override Ninject.IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<RequestScopeObject>().ToSelf().InRequestScope();
kernel.Bind<SingletonScopeObject>().ToSelf().InSingletonScope();
return kernel;
}
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
// init cache
this.Kernel.Get<SingletonScopeObject>().Init();
}
但是你必须在使用RequestScopeObject
之后做清理(例如Dispose()
它,如果它实现了IDisposable
)。
public class SingletonScopeObject
{
private string cache;
private RequestScopeObject requestScopeObject;
public SingletonScopeObject(RequestScopeObject requestScopeObject)
{
this.requestScopeObject = requestScopeObject;
}
public void Init()
{
cache = this.requestScopeObject.GetData();
// do cleanup
this.requestScopeObject.Dispose();
this.requestScopeObject = null;
}
public string GetCache()
{
return cache;
}
}
另一种方法
使用条件绑定将InRequestScope
和InSingletonScope
同时绑定到RequestScopeObject
:
kernel.Bind<SingletonScopeObject>()
.ToSelf()
.InSingletonScope()
.Named("singletonCache");
// as singleton for initialization
kernel.Bind<RequestScopeObject>()
.ToSelf()
.WhenParentNamed("singletonCache")
.InSingletonScope();
// per request scope binding
kernel.Bind<RequestScopeObject>()
.ToSelf()
.InRequestScope();
初始化后的清理保持不变