5

J'essaie d'implémenter un modèle de référentiel générique. J'ai trouvé ce site qui je pense qu'il est bien expliqué. Mon but est de faire gagner du temps et de la frappe aux développeurs et je sais que cela m'aidera.Modèle de référentiel générique avec motif UnitOfWork

J'ai donc 2 questions:
1. Est-ce une bonne approche ou non, aurai-je des problèmes dans le futur?
2. Comment puis-je le combiner avec le motif Unitofwork ?, Je ne peux pas créer une instance de la classe abstraite bien sûr, de sorte que le code suivant est invalide.

public class UnitOfWork : IDisposable 
    { 
     #region Private fields 
     private readonly MyCompanyContext _context = new MyCompanyContext(); 
     private GenericRepository<MyCompanyContext, Task> _taskRepository; 

     public GenericRepository<MyCompanyContext, Task> TaskRepository 
     { 
      get 
      { 
       return _taskRepository ?? 
         (_taskRepository = new GenericRepository<MyCompanyContext, Task>()); 
      } 
     } 




namespace MyCompany.DAL.Repository 
{ 
    public interface IGenericRepository<T> where T : class 
    { 
     IQueryable<T> GetAll(); 
     IQueryable<T> FindBy(Expression<Func<T, bool>> predicate); 
     void Add(T entity); 
     void Delete(T entity); 
     void Edit(T entity); 
     void Save(); 
    } 

    public abstract class GenericRepository<C, T> : 
    IGenericRepository<T> 
     where T : class 
     where C : DbContext, new() 
    { 

     private C _entities = new C(); 
     public C Context 
     { 

      get { return _entities; } 
      set { _entities = value; } 
     } 

     public virtual IQueryable<T> GetAll() 
     { 

      IQueryable<T> query = _entities.Set<T>(); 
      return query; 
     } 

     public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate) 
     { 
      IQueryable<T> query = _entities.Set<T>().Where(predicate); 
      return query; 
     } 

     public virtual void Add(T entity) 
     { 
      _entities.Set<T>().Add(entity); 
     } 

     public virtual void Delete(T entity) 
     { 
      _entities.Set<T>().Remove(entity); 
     } 

     public virtual void Edit(T entity) 
     { 
      _entities.Entry(entity).State = System.Data.EntityState.Modified; 
     } 

     public virtual void Save() 
     { 
      _entities.SaveChanges(); 
     } 
    } 
} 

Répondre

5

Il y a plusieurs opinions sur les dépôts, mais après avoir essayé différentes implémentations du référentiel dans la production depuis des années couple moi-même, je suis d'accord avec l'opinion Ayende's, ce référentiel, en particulier générique, est couche d'abstraction redondante.

J'ai beaucoup aimé ce cours: http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/linq-architecture

Il a marché dans la plupart des solutions possibles et expliquer les biens et Bads. Ce que nous utilisons en ce moment est une abstraction très fine sur le datacontext, juste pour surmonter les problèmes de testabilité de Linq2Sql, qui sont hors de propos dans la plupart des cas lors de l'utilisation de EF.

2

Avec beaucoup d'efforts, vous pourriez obtenir ce travail, mais je me demande si l'effort en vaut vraiment la peine? J'ai déjà vu des implémentations comme celle-ci, et ils ont vraiment du mal à gérer les relations plusieurs-à-plusieurs (pensez à la façon dont vous géreriez cela dans votre scénario). Vous utilisez Entity Framework, un droit ORM? ORMs comme Entity Framework et nHibernate sont conçu pour abstraire l'implémentation de base de données à partir du code de l'application, alors quel est le but d'ajouter encore une autre abstraction dessus pour gérer les entités à un tel niveau granulaire? S'il s'agit d'une question de test, vous pouvez utiliser un cadre de simulation pour se moquer du contexte, supprimant ainsi le besoin d'une base de données réelle pendant le test. Si toutefois, pour des raisons d'architecture ou de sécurité, vous cherchez à supprimer les interactions avec un contexte db de votre code d'application, je recommanderais pour le pragmatisme d'utiliser une implémentation du modèle de commande au-dessus de l'infrastructure. J'ai dû faire cela sur une application d'entreprise (bancaire) à plus grande échelle où pour des raisons de sécurité (à tort ou à raison) nous n'avions absolument pas le droit d'avoir une connexion db dans notre code d'application.

+0

Je ne pense pas que j'ajoute une autre couche d'abstraction, je fais simplement simplement mon code pour le rendre plus facile à utiliser. Avec le modèle de dépôt générique je pourrais faire le CRUD de manière très efficace. Mais c'est pourquoi j'ai posé ma première question en premier lieu, aurais-je des problèmes techniques avec cette approche? –

+0

Oui, vous avez raison, avec UOW vous n'ajoutez pas vraiment une autre couche d'abstraction. Je pense cependant que, sauf dans des scénarios très simples, l'UOW n'est pas très utile, et oui, je pense que vous pourriez avoir des problèmes techniques si vous devez gérer des relations many-to-many. –

+0

@LuisEValencia> hm, je ne vois pas comment cela simplifie votre code? – Giedrius

Questions connexes