Dopo aver letto e provato molte cose con l'ultima versione stabile (6.1.1) di Entity Framework
.Codice EF6 Prima con repository generico e Dipendenza dell'iniezione e SoC
sto leggendo un sacco di contraddizioni circa se o non utilizzare i repository con EF6
o EF
in generale, perché è DbContext
fornisce già un repository e DbSet
il UoW
, fuori dalla scatola.
Lasciatemi prima spiegare cosa contiene la mia soluzione in termini di progetto e poi tornerò alla contraddizione.
Ha un progetto di libreria di classi e un progetto asp.net-mvc
. Il progetto class lib è l'accesso ai dati e dove Migrations
sono abilitati per Code First
.
Nel mio progetto lib classe ho un repository generico:
public interface IRepository<TEntity> where TEntity : class
{
IEnumerable<TEntity> Get();
TEntity GetByID(object id);
void Insert(TEntity entity);
void Delete(object id);
void Update(TEntity entityToUpdate);
}
E qui è la realizzazione di esso:
public class Repository<TEntity> where TEntity : class
{
internal ApplicationDbContext context;
internal DbSet<TEntity> dbSet;
public Repository(ApplicationDbContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get()
{
IQueryable<TEntity> query = dbSet;
return query.ToList();
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
E qui qualche entità:
public DbSet<User> User{ get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<UserOrder> UserOrders { get; set; }
public DbSet<Shipment> Shipments { get; set; }
Non so cosa ripetermi ma, con EF6
non si passano più repository, ma il DbContext
invece. Così per DI
Ho installato il seguente nel progetto asp-net-mvc
utilizzando Ninject
:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
}
E questo sarà iniettare il ApplicationDbContext
tramite iniezione di costruzione per classi di livello superiore, se del caso.
Ora tornando alla contraddizione.
Se non abbiamo più bisogno di un repository perché EF
fornisce già quello pronto, come facciamo Separation of Concern
(abbreviato in SoC nel titolo)?
Ora correggimi se ho torto, ma mi sembra che ho solo bisogno di fare tutti i calcoli/calcoli di accesso ai dati (come aggiungere, recuperare, aggiornare, cancellare e qualche logica/calcoli personalizzati qua e là (entità specifica)) nel progetto asp.net-mvc
, se non aggiungo un repository.
Qualsiasi luce su questo argomento è molto apprezzata.
E 'solo una questione di come astratto si può ottenere. Il contesto EF * è * in effetti un repository, ma un repository molto ponderato con un proprio insieme di metodi specifici del database relazionale. Se vuoi astrarre anche quello, dovrai avvolgere EF con il tuo repository generico. – haim770
La contraddizione che ho letto su internet è la cosa che mi ha infastidito di più. Ma ora ci siamo chiariti, mi piacerebbe sapere qual è la strada da percorrere. Chris Pratt dice con i servizi. Che ne dici? – Quoter
I servizi sono sempre esistiti (e resi molto popolari a causa dell'influenza del design basato sul dominio) ma non penso che siano destinati a * sostituire * i repository. Per quanto ho capito, sono semplicemente una facciata per azioni e query comuni, e nella maggior parte delle implementazioni vedrai un 'IRepository' che si sta iniettando in esso. Alla fine, tutto dipende dallo scopo del tuo progetto. Dovete chiedervi quanto sia importante per il progetto il livello di astrazione che scegliete e quanto esattamente lo influenzerà a lungo termine, specialmente per quanto riguarda la testabilità e la scalabilità. – haim770