2012-06-22 9 views
5

: Ich bin sowohl EF und Ninject mich so vergeben, wenn dies keinen Sinn macht :)DbContext Angeordnet nach dem ersten Anfrage bei der Verwendung von Ninject des InRequestScope()

Ich habe eine MVC3 Anwendung mit dem Ninject und Ninject.Web. Gemeinsame Referenzen. Ich versuche, einen DbContext in meine Repositories zu injizieren. Was ich sehe, ist, dass auf der ersten Anfrage, alles funktioniert wunderbar, aber die nachfolgenden Anforderungen zurück:

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) 

Meine Bindungen:

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

Meine Service-Klasse:

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

    ... 
} 

Mein Repository Klasse:

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

    ... 
} 

Meine SiteDataContext Klasse:

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

Mein Controller:

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

    ... 
} 

Wenn ich .InRequestScope() entfernen, dann funktioniert es gut - aber dann, dass Probleme mit Entity Framework verursacht, da Objekte in mehreren separaten geändert werden Instanzen des Datenkontextes.

Antwort

5

Natürlich, bald nach dem Posten etwas geklickt in meinem Kopf, und ich war in der Lage, dies zu lösen.

Das Problem liegt in der Tatsache, dass das Verhalten von ActionFilters in MVC3 geändert wurde und ich einen Filter hatte, der mein ProductService injiziert hat.

Ich nehme an, dass der Filter des Dienstes entsorgt und dass schließlich der DbContext entsorgt.

In meinem Fall war die Lösung einfach. Ich habe einen zweiten DbContext erstellt, der speziell für meinen Filter verwendet wird. Da der Filter nichts anderes tut, als einige ausgewählte Tabellen abzufragen, um die Berechtigung für bestimmte Ressourcen zu überprüfen, brauchte ich den Einheitsarbeitskontext, den DbContext für eine einzige Anforderung bereitstellt, nicht. Ich habe einen neuen Dienst erstellt, der den neuen DbContext verwendet. In diesem Fall ist es ausreichend, mit InTransientScope() konfiguriert zu werden.

6

Legen Sie Ihre Repositorys auch als InRequestScope fest. Sie sollten nach jeder Anfrage entsorgen.

Auch mit MVC sollten Sie Konstruktor-Injektion verwenden, um Ihr Repository in Ihre Controller-Instanz zu injizieren.

+0

Gibt es einen Vorteil für die Konstruktorinjektion gegenüber der Attributeinspritzung? –

+1

Absolut, es haftet an der Zusammensetzung Wurzel. Die Verwendung von Attributen für dieses Muster ist aus mehreren Gründen nicht geeignet. Die Verwendung der Konstruktorinjektion funktioniert hier gut, und es ermöglicht Abhängigkeiten zum frühestmöglichen Zeitpunkt bekannt zu machen, und da es keinen Grund gibt, dies als eine optionale Abhängigkeit mit einem Standardwert zu betrachten, ist dies die bevorzugte Methode. Siehe http://www.manning.com/seemann/ welches das beste Buch zu diesem Thema ist. –

+1

Ich verwende DependencyResolver.Current.GetService <... anstelle von Costrusor-Injektion. Ist es möglich, dass dies das gleiche Problem verursacht? (Die Operation kann nicht abgeschlossen werden, da der DbContext entfernt wurde) –

Verwandte Themen