2012-06-22 2 views
5

Sono nuovo di entrambi EF e Ninject quindi perdonatemi se questo non ha senso :)DbContext Disposto dopo la prima richiesta quando si utilizza InRequestScope di Ninject()

Ho un'applicazione MVC3 con la Ninject e Ninject.Web. Riferimenti comuni Sto cercando di iniettare un DbContext nei miei repository. Quello che sto vedendo è che alla prima richiesta, tutto funziona a meraviglia, ma le successive richieste di ritorno:

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) 

miei attacchi:

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

La mia classe di servizio:

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

    ... 
} 

mio repository classe:

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

    ... 
} 

La mia classe 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); 
    } 
} 

mio regolatore:

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

    ... 
} 

Se rimuovo .InRequestScope(), allora funziona bene - ma d'altra parte che causa problemi con Entity Framework dato che gli oggetti vengono modificati in molteplici separata istanze del contesto dei dati.

risposta

5

Naturalmente, subito dopo la pubblicazione è scattato qualcosa nella mia mente, e sono stato in grado di risolvere questo.

Il problema sta nel fatto che il comportamento di ActionFilters sono stati modificati in MVC3 e ho avuto un filtro che aveva il mio ProductService iniettato.

suppongo che il filtro smaltito del servizio e che alla fine smaltito il DbContext.

Nel mio caso, la soluzione era semplice. Ho creato un secondo DbContext che viene utilizzato specificamente per il mio filtro. Poiché il filtro non fa altro che interrogare alcune tabelle selezionate per verificare l'autorizzazione a risorse specifiche, non avevo bisogno del contesto Unità di lavoro che DbContext fornisce attraverso una singola richiesta. Ho creato un nuovo servizio che utilizza il nuovo DbContext. In questo caso, è sufficiente essere configurato con InTransientScope()

6

Impostare i repository di essere InRequestScope pure. Dovrebbero disporre dopo ogni richiesta.

Anche con MVC si dovrebbe utilizzare l'iniezione del costruttore per iniettare il repository nella tua istanza di controllo pure.

+0

C'è un beneficio per l'iniezione del costruttore vs iniezione attributo? –

+1

Assolutamente, aderisce alla radice della composizione. Utilizzare gli attributi per questo modello non è appropriato per diversi motivi. L'uso dell'iniezione del costruttore funziona bene qui e consente alle dipendenze di essere conosciute il più presto possibile e poiché non c'è motivo di avere questa dipendenza come dipendenza opzionale con un valore predefinito, qui è il metodo preferito. Vedi http://www.manning.com/seemann/ che è il miglior libro imho sull'argomento. –

+1

Sto usando DependencyResolver.Current.GetService <... invece dell'iniezione del costruttore. È possibile che questo stia causando lo stesso problema? (L'operazione non può essere completata perché DbContext è stato eliminato) –