1

リクエストごとに作成する必要のあるリポジトリがあります。これで、そのリポジトリを使用してデータを入力する必要があるシングルトンキャッシングオブジェクトがありますが、このオブジェクトはApplication_Startイベントで初期化されるため、リクエストコンテキストはありません。

Ninjectでこれを達成するための最良の方法はどれですか?

ありがとう。

4

1 に答える 1

1

アプリの起動時に現在HttpContextが欠落しているため(IIS7統合モードの場合)、Ninjectは、アプリの起動への依存性を注入しようとInRequestScopeしたときと同じように、バインドされたオブジェクトを確実に処理します。InTransientScopeNinject(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バインドされたオブジェクトは、アプリの起動時にバインドされた場合と同じように扱われます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();

初期化後のクリーンアップは同じままです。

于 2013-01-18T00:07:09.320 に答える