Attualmente sto progettando una soluzione di livello n che utilizza Entity Framework 5 (.net 4) come strategia di accesso ai dati, ma sono preoccupato su come incorporare l'iniezione di dipendenza per renderla verificabile / flessibile.
Il layout della mia soluzione attuale è il seguente (la mia soluzione si chiama Alcatraz):
Alcatraz.WebUI : un progetto webform asp.net, l'interfaccia utente front-end, fa riferimento ai progetti Alcatraz.Business e Alcatraz.Data.Models .
Alcatraz.Business : un progetto di biblioteca di classe, contiene la logica aziendale, fa riferimento a progetti Alcatraz.Data.Access , Alcatraz.Data.Models
Alcatraz.Data.Access : un progetto di biblioteca di classe, ospita AlcatrazModel.edmx e AlcatrazEntities
DbContext, fa riferimento a progetti Alcatraz.Data.Models .
Alcatraz.Data.Models : un progetto di biblioteca di classe, contiene POCO per il modello Alcatraz, nessun riferimento.
La mia visione di come funzionerebbe questa soluzione è che il web-ui avrebbe un'istanza di un repository all'interno della biblioteca aziendale, questo repository avrebbe una dipendenza (attraverso il costruttore) di una stringa di connessione (non AlcatrazEntities
un'istanza). Il web-ui conosceva le stringhe di connessione al database, ma non che si trattasse di una stringa di connessione del framework di entità.
Nel progetto aziendale:
public class InmateRepository : IInmateRepository
{
private string _connectionString;
public InmateRepository(string connectionString)
{
if (connectionString == null)
{
throw new ArgumentNullException("connectionString");
}
EntityConnectionStringBuilder connectionBuilder = new EntityConnectionStringBuilder();
connectionBuilder.Metadata = "res://*/AlcatrazModel.csdl|res://*/AlcatrazModel.ssdl|res://*/AlcatrazModel.msl";
connectionBuilder.Provider = "System.Data.SqlClient";
connectionBuilder.ProviderConnectionString = connectionString;
_connectionString = connectionBuilder.ToString();
}
public IQueryable<Inmate> GetAllInmates()
{
AlcatrazEntities ents = new AlcatrazEntities(_connectionString);
return ents.Inmates;
}
}
Nell'interfaccia utente Web:
IInmateRepository inmateRepo = new InmateRepository(@"data source=MATTHEW-PC\SQLEXPRESS;initial catalog=Alcatraz;integrated security=True;");
List<Inmate> deathRowInmates = inmateRepo.GetAllInmates().Where(i => i.OnDeathRow).ToList();
Ho alcune domande correlate su questo disegno.
Questo design ha senso anche in termini di funzionalità di Entity Frameworks? Ho sentito che il framework Entity utilizza già il modello Unit-of-work, sto semplicemente aggiungendo un altro livello di abstract inutilmente?
Non voglio che il mio web-ui comunichi direttamente con Entity Framework (o addirittura lo faccia riferimento a tale proposito), voglio che tutti gli accessi al database passino attraverso il livello aziendale poiché in futuro avrò più progetti utilizzando lo stesso livello aziendale (servizio web, applicazione Windows, ecc.) e voglio che sia facile da mantenere / aggiornare avendo la logica di business in un'area centrale. È un modo appropriato per raggiungere questo obiettivo?
Il livello aziendale dovrebbe contenere anche repository o dovrebbe essere contenuto nel livello Access? Se dove si trovano va bene, passare una stringa di connessione è una buona dipendenza da assumere?
Grazie per aver dedicato del tempo a leggere!
DbContext
come sua dipendenza. Le business class hanno repository come dipendenza. Per l'iniezione di dipendenza, lo sto facendo manualmente (quindi capisco cosa sta succedendo). Il motivo per cui voglio essere in grado di impostare la stringa di connessioneDbContext
è l'uso del database sharding, quindi in alcuni casi ho bisogno di avere un framework di entità per connettermi a database diversi (della stessa struttura). Ti capisco bene?