1

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

使用 Ninject 实现这一目标的最佳方法是哪一种?

谢谢。

4

1 回答 1

1

由于HttpContext应用程序启动时缺少电流(在 IIS7 集成模式下),Ninject 肯定会InRequestScopeInTransientScope您尝试注入对应用程序启动的依赖项一样处理对象绑定。正如我们在 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.Currentnull在应用程序启动时,因此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两者InRequestScopeInSingletonScope使用条件绑定,如下所示:

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();

初始化后的清理保持不变。

于 2013-01-18T00:07:09.320 回答