7

I progetti in mia soluzione sono impostati in questo modo:Iniettare DbContext nella libreria di classi Repository

  • App.Data
  • App.Models
  • App.Web

In App. Dati, sto utilizzando Entity Framework per accedere ai miei dati con un gruppo di repository per interagire in astratto con esso. Per ovvi motivi, desidero che App.Web faccia riferimento solo al progetto App.Data e non a Entity Framework.

sto usando Constructor iniezione per dare ai miei controllori un riferimento a un contenitore repository che assomiglia a questo:

public interface IDataRepository 
{ 
    IUserRepository User { get; set; } 
    IProductRepository Product { get; set; } 

    // ... 
} 

public class DataRepository : IDataRepository 
{ 
    private readonly AppContext _context; 

    public DataRepository(AppContext context) 
    { 
     _context = context; 
    } 

    // ... 
} 

DataRepository avrà un oggetto AppContext (che eredita da Entity Framework di DbContext) che tutto il bambino I repository useranno per accedere al database.

Quindi, finalmente, arriviamo al mio problema: , come utilizzare Constructor Injection su DataRepository considerando che si tratta di una libreria di codici e non ha un punto di ingresso? Non riesco a eseguire il bootstrap AppContext in App.Web perché quindi devo fare riferimento a Entity Framework da quel progetto.

Oppure sto facendo qualcosa di stupido?

+0

Non è una risposta alla tua domanda, ma invece di definire un sacco di interfacce repository, cercare di definire un unico '' interfaccia IRepository, come spiegato [qui] (http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92). Ciò consente molta più flessibilità. – Steven

+3

@Steven Grazie per il tuo commento. Preferisco i repository specifici per questo motivo: "un repository è una parte del dominio che viene modellato e quel dominio non è generico, non tutte le entità possono essere eliminate, non tutte le entità possono essere aggiunte, non tutte le entità hanno un repository". http://stackoverflow.com/questions/1230571/advantage-of-creating-a-generic-repository-vs-specific-repository-for-each-obje – ajbeaven

risposta

12

È possibile definire una classe RepositoryConnection in App.Data che funge da wrapper per il contesto e rimuove la necessità di fare riferimento a EF in App.Web. Se si utilizza un contenitore IoC è possibile controllare la durata della classe RepositoryConnection per garantire che tutte le istanze di Repository ottengano lo stesso contesto. Questo è un esempio semplificato ...

public class RepositoryConnection 
{ 
    private readonly AppContext _context; 

    public RepositoryConnection() 
    { 
     _context = new AppContext(); 
    } 

    public AppContext AppContext { get { return _context; } } 
} 

public class DataRepository : IDataRepository 
{ 
    private readonly AppContext _context; 

    public DataRepository(RepositoryConnection connection) 
    { 
     _context = connection.AppContext; 
    } 

// ... 
} 
+0

Ah, naturalmente! Votate quest'uomo! – ajbeaven

+0

Se tutte le classi ottengono lo stesso contesto, nessuno smaltisce il contesto EF, che è cattivo, molto cattivo. I contesti EF sono progettati con l'idea di istanziare, utilizzare e disporre. –

+0

@BrunoBrant sei assolutamente corretto - un 'Context' dovrebbe essere il più breve possibile e questa risposta lo supporta pienamente. Il fatto che abbiamo un 'RepositoryConnection' da fungere da' bridge' tra gli assembly non cambia nulla. Il 'RepositoryConnection' e quindi il' Context' sono registrati ** Per Web Request **. Ogni 'RepositoryConnection' (e quindi' Context') esisterà nell'ambito di una singola richiesta web e quindi sarà vivo per una questione di secondi. Non appena la richiesta Web è terminata, le classi gestite con DI diventeranno fuori ambito e saranno 'Disposed()'. – qujck

Problemi correlati