2012-06-22 5 views
5

を使用しているとき、私はEFとNinjectの両方に新しいです、これは意味がありませんので、もし私を許し:)DbContext配置されているのNinjectのInRequestScope()

私はNinjectとNinject.WebとMVC3アプリケーションを持っています。共通の参照。私は私のリポジトリにDbContextを注入しようとしています。私は何を見ていますと、最初の要求で、すべてが素晴らしく動作することであるが、その後の要求は返す:

System.InvalidOperationException: The operation cannot be completed because the DbContext has been disposed. 
    at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() 
    at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression) 
    at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) 

マイバインディング:

kernel.Bind<ISiteDataContext>().To<SiteDataContext>().InRequestScope(); 
kernel.Bind<IProductRepository>().To<ProductRepository>(); 
kernel.Bind<IProductService>().To<ProductService>(); 

私のサービスクラス:

public class ProductService : IProductService { 
    [Inject] 
    public IProductRepository repository {get; set;} 

    ... 
} 

マイ・リポジトリクラス:

public class ProductRepository : IProductRepository { 
    [Inject] 
    public ISiteDataContext context {get; set;} 

    ... 
} 

マイSiteDataContextクラス:

public class SiteDataContext : DbContext, ISiteDataContext 
{ 
    static SiteDataContext() 
    { 
     Database.SetInitializer<SiteDataContext >(null); 
    } 

    public DbSet<Product> Products{ get; set; } 


    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 
    } 
} 

マイコントローラ:

public class ProductController { 
    [Inject] 
    public IProductService productService {get; set;} 

    ... 
} 

私は.InRequestScope()を削除すると、それが正常に動作します - オブジェクトが複数の個別に変更されているので、Entity Frameworkのに問題が発生した後が、データコンテキストのインスタンス

答えて

5

当然のことながら、投稿した直後に私の心に何かがクリックされ、これを解決することができました。

MVC3でActionFiltersの動作が変更され、ProductServiceが注入されたフィルタがあるという問題があります。

私はフィルタがサービスを処理し、最終的にDbContextを廃棄したとします。

私の場合、解決策は簡単でした。私は特に私のフィルタに使用される2番目のDbContextを作成しました。フィルタは、特定のリソースへの権限を確認するために選択されたいくつかのテーブルを照会するだけであるため、DbContextが単一の要求で提供する作業単位コンテキストは必要ありません。新しいDbContextを使用する新しいサービスを作成しました。この場合、InTransientScope()で設定すれば十分です

6

あなたのリポジトリもInRequestScopeに設定してください。彼らは各要求の後に処分する必要があります。

また、MVCでは、コントローラインスタンスにリポジトリを挿入するためにコンストラクタインジェクションを使用する必要があります。

+0

コンストラクタインジェクションと属性インジェクションの利点はありますか? –

+1

もちろん、それは合成ルートに従います。このパターンのuse属性は、いくつかの理由で適切ではありません。コンストラクタインジェクションの使用はここでうまくいきます。可能な限り早い時期に依存関係を知ることができます。また、これをオプションの依存関係として使用する理由もありません。 http://www.manning.com/seemann/を参照してください。 –

+1

私はDependencyResolver.Current.GetService <...を使用しています。これが同じ問題を引き起こす可能性はありますか? (DbContextが破棄されているため、操作を完了できません) –