0

現在、Entity Framework (DbContext) を使用して既存のサービス レイヤーに接続する Windows サービスを作成しており、Ninject を使用して Respositories と DbContext インスタンスを注入しています。これは、スレッドが実行されるたびに新しい DbContext インスタンスが必要ですが、現時点では、スレッドの存続期間全体で同じインスタンスを取得しています。

私のバインディングは次のようになります。

Bind<IDbContext>().To<EnterpriseDbContext>().InThreadScope();
Bind<IUserRepository>().To<UserRepository>().InThreadScope();
// And other repositories

そして、私のスレッドコードは次のようになります:

[Inject]
public IDbContext DbContext { get; set; }

// Execute indefinitely (or until we've stopped)
while (true && !isStopping)
{
   try
   {
      // Do work.

      // Save any changes.
      DbContext.SaveAnyChanges();
    } 
    catch (Exception ex)
    {
       // Handle exception
       HandleException(ex);
    }

    // Sleep
    Thread.Sleep(sleepInterval);
 }

これで、スコープを InTransientScope() などに変更できることがわかりましたが、Ninject にはまだ慣れていないので、毎回新しい DbContext インスタンスを使用するようにコードを整理する方法がよくわかりません。

誰かが似たようなことをしたことがありますか?Web アプリには、完全に機能する InRequestScope() がありますが、Windows サービスで DbContext を使用する方法については、ここでの最善のアプローチがよくわかりません。

4

1 に答える 1

3

答えはこちらをご覧ください

Ninject2 では、次の方法でこれを行うことができます。

Bind<IService>().To<ServiceImpl>().InScope(ctx => ...);

に渡されたコールバックによって返されたオブジェクトInScope()は、スコープ内でアクティブ化されたインスタンスの「所有」オブジェクトになります。これには 2 つの意味があります。

  1. コールバックが複数のアクティベーションに対して同じオブジェクトを返す場合、Ninject は最初のアクティベーションからインスタンスを再利用します。

  2. コールバックから返されたオブジェクトがガベージ コレクションされると、Ninject はそのオブジェクトに関連付けられたすべてのインスタンスを非アクティブ化します (「ティア ダウン」、Dispose() の呼び出しなど)。

たとえば、使用されるコールバックは次のInRequestScope()とおりです。

ctx => HttpContext.Current

HttpContext.Currentは Web リクエストごとに の新しいインスタンスに設定されるためHttpContext、リクエストごとにサービスのインスタンスが 1 つだけアクティブ化され、リクエストが終了してHttpContext(最終的に) が収集されると、インスタンスは非アクティブ化されます。

INotifyWhenDisposedコールバックによって返されるオブジェクトは、「所有されている」インスタンスを確定的に非アクティブ化する場合、Ninject からのインターフェースであるも実装できます。スコーピング オブジェクトがこのインターフェイスを実装している場合、それが Dispose() されると、それが所有するすべてのインスタンスが直ちに非アクティブ化されます。

于 2013-09-06T11:23:14.057 に答える