Structure de l'entité 4 CTP 4 / CTP 5 Schéma générique du dépôt et unité Testable

je joue avec la dernière version CTP 5 D'Entity Framework et la construction d'un simple asp.net MVC blog où je n'ai que deux tables: Post et commentaires. Cela se fait entièrement en POCO, j'ai juste besoin d'aide sur la partie DbContext, où j'ai besoin qu'elle soit testable à l'unité (en utilisant IDbSet?) et j'ai besoin d'un modèle de dépôt simple / générique pour ajouter, mettre à jour, supprimer, récupérer. Toute aide est appréciée.

Merci.

24
demandé sur Saxman 2010-12-14 21:34:23

3 réponses

démarrer avec vous DbContext, créer un nouveau fichier appelé base de données.cs:

de la Base de données.cs

public class Database : DbContext
    {

        private IDbSet<Post> _posts;

        public IDbSet<Post> Posts {
            get { return _posts ?? (_posts = DbSet<Post>()); }
        }

        public virtual IDbSet<T> DbSet<T>() where T : class {
            return Set<T>();
        }
        public virtual void Commit() {
            base.SaveChanges();
        }
}

définir un IDatabaseFactory et l'appliquer avec DatabaseFactory:

IDatabaseFactory.cs

public interface IDatabaseFactory : IDisposable
    {
        Database Get();
    }

DatabaseFactory.cs

public class DatabaseFactory : Disposable, IDatabaseFactory {
        private Database _database;
        public Database Get() {
            return _database ?? (_database = new Database());
        }
        protected override void DisposeCore() {
            if (_database != null)
                _database.Dispose();
        }
    }

extension jetable méthode:

jetable.cs

public class Disposable : IDisposable
    {
        private bool isDisposed;

        ~Disposable()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        private void Dispose(bool disposing)
        {
            if(!isDisposed && disposing)
            {
                DisposeCore();
            }

            isDisposed = true;
        }

        protected virtual void DisposeCore()
        {
        }
    }

maintenant nous pouvons définir notre IRepository et notre RepositoryBase

IRepository.cs

public interface IRepository<T> where T : class
{
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    T GetById(long Id);
    IEnumerable<T> All();
    IEnumerable<T> AllReadOnly();
}

RepositoryBase.cs

public abstract class RepositoryBase<T> where T : class
    {
        private Database _database;
        private readonly IDbSet<T> _dbset;
        protected RepositoryBase(IDatabaseFactory databaseFactory)
        {
            DatabaseFactory = databaseFactory;
            _dbset = Database.Set<T>();
        }

        protected IDatabaseFactory DatabaseFactory
        {
            get; private set;
        }

        protected Database Database
        {
            get { return _database ?? (_database = DatabaseFactory.Get()); }
        }
        public virtual void Add(T entity)
        {
            _dbset.Add(entity);
        }

        public virtual void Delete(T entity)
        {
            _dbset.Remove(entity);
        }

        public virtual void Update(T entity)
        {
            _database.Entry(entity).State = EntityState.Modified;
        }
        public virtual T GetById(long id)
        {
            return _dbset.Find(id);
        }

        public virtual IEnumerable<T> All()
        {
            return _dbset.ToList();
        }
        public virtual IEnumerable<T> AllReadOnly()
        {
            return _dbset.AsNoTracking().ToList();
        }
    }

Maintenant vous pouvez créer votre IPostRepository et PostRepository:

IPostRepository.cs

     public interface IPostRepository : IRepository<Post>
        {
            //Add custom methods here if needed
            Post ByTitle(string title);
        }

Postrépositaire.cs

    public class PostRepository : RepositoryBase<Post>, IPostRepository
        {
            public PostRepository(IDatabaseFactory databaseFactory) : base(databaseFactory)
            {
            }
            public Post ByTitle(string title) {
                return base.Database.Posts.Single(x => x.Title == title);
            }
        }

enfin, le UoW:

IUnitOfWork.cs

public interface IUnitOfWork
{
    void Commit();
}

Unité de travail.cs

private readonly IDatabaseFactory _databaseFactory;
private Database _database;

public UnitOfWork(IDatabaseFactory databaseFactory)
{
    _databaseFactory = databaseFactory;
}

protected Database Database
{
    get { return _database ?? (_database = _databaseFactory.Get()); }
}

public void Commit()
{
    Database.Commit();
}

utilisant dans votre contrôleur:

private readonly IPostRepository _postRepository;
private readonly IUnitOfWork_unitOfWork;

        public PostController(IPostRepository postRepository, IUnitOfWork unitOfWork)
        {
            _postRepository = postRepository;
            _unitOfWork = unitOfWork;
        }

        public ActionResult Add(Post post) {
            _postRepository.Add(post);
            _unitOfWork.Commit();
        }

vous aurez besoin utiliser un conteneur IoC comme StructureMap pour que cela fonctionne. Vous pouvez installer structure map via NuGet, ou si vous utilisez MVC 3, vous pouvez installer le paquet StructureMap-MVC NuGet. (Liens Ci-Dessous)

Install-Package StructureMap.MVC4

Install-Package StructureMap.MVC3

Install-Package Structuremap

si vous avez des questions laissez-moi savoir. Espérons que cela aide.

50
répondu Paul 2013-05-10 18:58:13

j'adore cette article détaillé sur Entity Framework 4 POCO, Référentiel et Spécification du Modèle

http://huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern /

9
répondu Korayem 2011-01-26 11:10:47

la seule chose que je ferais différemment, c'est dans l'implémentation, c'est - à-dire exposer L'IPostRepository dans la couche service et avoir un champ d'interface de type IPostService dans le contrôleur tout comme une autre couche d'abstraction, mais sinon c'est un bon exemple-nice one, Paul.

1
répondu santos 2011-01-10 19:40:06