“每request"激活上下文…没有要求

本文关键字:上下文 激活 request quot | 更新日期: 2023-09-27 17:54:10

我有一个需要为每个请求创建的存储库。现在有一个单例缓存对象需要使用存储库来填充数据,但是这个对象是在Application_Start事件中初始化的,因此没有请求上下文。

用Ninject实现这一点的最好方法是什么?

谢谢。

“每request"激活上下文…没有要求

由于当前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;
    }
}

另一种方法

使用条件绑定将InRequestScopeInSingletonScope同时绑定到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();

初始化后的清理保持不变