我有一个需要根据请求创建的存储库。现在有一个单独的缓存对象需要使用该存储库来填充数据,但是这个对象在Application_Start事件中初始化,因此没有请求上下文。
哪个是使用Ninject完成此任务的最佳方式?
感谢。
答案 0 :(得分:1)
由于应用启动时缺少当前HttpContext
(在IIS7集成模式下)当您尝试在app上注入依赖时,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
,因此{app}启动时会对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;
}
}
另一种方法
使用条件绑定绑定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();
初始化后的清理工作保持不变。