2013-03-11 10 views
10

NuGetのNinject.Web.WebApi-RCパッケージを使用しているため、属性とフィルタを使用して単純なリポジトリパターンを推奨hereとして使用しています。Ninject WebAPI DbContextが破棄されたため、操作を完了できません

これは最初のリクエストでは機能しますが、DbContextがリクエストスコープにあるため、後続のすべてのリクエストに配置されます。ここで

は私の属性である:ここでは

public class CommunicationKeyValidationAttribute : FilterAttribute 
{ 
} 

は私のフィルタである:ここでは

public class CommunicationKeyValidationFilter : AbstractActionFilter 
{ 
    public CommunicationKeyValidationFilter(IRepository repository) 
    { 
     this.repository = repository; 
    } 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     // do stuff 
    } 
} 

は私のリポジトリです。ここ

public class Repository : IRepository 
{ 
    public Repository(MyDbContext dbContext) 
    { 
     this.dbContext = dbContext; 
    } 
} 

は私のNinjectバインディングです:

this.Kernel.Bind<MyDbContext>().ToSelf().InRequestScope(); 
this.Kernel.Bind<IRepository>().To<Repository>().InRequestScope(); 
this.Kernel.BindHttpFilter<CommunicationKeyValidationFilter>(FilterScope.Action) 
     .WhenActionMethodHas<CommunicationKeyValidationAttribute>() 
     .InRequestScope(); 

私のコントローラは、次のようになります。ここ

public class HomeController 
{ 
    [CommunicationKeyValidation] 
    public ActionResult Index() 
    { 
     // do stuff 
    } 

問題CommunicationKeyValidationFilter上のコンストラクタは最初の要求に応じて呼び出されていることです。フィルタを解決しようとするたびに、このフィルタを構築する方法がありますか?

+0

は:(?バグ)ので、私は、この機能によって引き起こされるweb.apiにNinjectのバグだと思います。 Web.Api自体がフィルタをキャッシュしているようです。私は[autofac web.api integration](https://code.google.com/p/autofac/wiki/WebApiIntegration)でこれを見つけました。「MVCのフィルタプロバイダとは異なり、 Web APIのフィルタ属性では、フィルタインスタンスをキャッシュしないように指定することはできません。つまり、Web APIのすべての**フィルタ属性は、アプリケーションのライフタイム全体にわたって存在する実質的にシングルトンのインスタンスです** ** " – nemesv

+0

うん、私は同じ記事を読むと信じています。私は、誰かがカスタムフィルタプロバイダを書くか、リクエストごとに新しいインスタンスを作成するものを書くことでこれに取り組んでいたのだろうかと思いました。 –

+0

興味深いことに、NinjectはWeb.APIの2つのフィルタプロバイダ 'DefaultFilterProvider'と' NinjectFilterProvider'を提供しています... – nemesv

答えて

15

フィルタはWebApiによってキャッシュされます。 WebApiがライフサイクルを管理できるように、これらは一時的な範囲内にある必要があります。ライフサイクルが長いため、ライフサイクルが短い依存関係はありません。

あなたができることは、フィルタの実行中にリポジトリを作成することです。このためには、使用して工場を注入するのが最善ですNinjectFactoryExtension:私はあなたの問題をREPROすることができました

public class CommunicationKeyValidationFilter : AbstractActionFilter 
{ 
    public CommunicationKeyValidationFilter(IRepositoryFactory repositoryFactory) 
    { 
     this.repositoryFactory = repositoryFactory; 
    } 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     var repository = this.repositoryFactory.CreateRepository(); 
    } 
} 

public interface IRepositoryFactory { IRepository CreateRepository(); } 
kernel.Bind<IRepositoryFactory>().ToFactory(); 
+1

ありがとうございます。これはコンストラクタインジェクションを使用するだけでは便利ではありませんが、私の問題を解決します。 –

+0

@RemoこのWebApi固有のフィルタのキャッシュはありますか? MVCフィルターにも工場を使うべきですか?あなたのすべての仕事に感謝します。 – kenchilada

+0

いいえWebAPI固有のものではありません。 Mvcは同じです –

関連する問題