我有一个需要根据请求创建的存储库。现在有一个单例缓存对象需要使用该存储库来填充自己的数据,但是该对象在 Application_Start 事件中初始化,因此没有请求上下文。
使用 Ninject 实现这一目标的最佳方法是哪一种?
谢谢。
我有一个需要根据请求创建的存储库。现在有一个单例缓存对象需要使用该存储库来填充自己的数据,但是该对象在 Application_Start 事件中初始化,因此没有请求上下文。
使用 Ninject 实现这一目标的最佳方法是哪一种?
谢谢。
由于HttpContext
应用程序启动时缺少电流(在 IIS7 集成模式下),Ninject 肯定会InRequestScope
像InTransientScope
您尝试注入对应用程序启动的依赖项一样处理对象绑定。正如我们在 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
绑定的对象将在应用程序启动时以与 bind 相同的方式处理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;
}
}
另一种方法
绑定你的RequestScopeObject
两者InRequestScope
并InSingletonScope
使用条件绑定,如下所示:
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();
初始化后的清理保持不变。