实体框架4 CTP 4/5 CTP通用存储库模式和单元测试 [英] Entity Framework 4 CTP 4 / CTP 5 Generic Repository Pattern and Unit Testable

查看:124
本文介绍了实体框架4 CTP 4/5 CTP通用存储库模式和单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打了最新的实体框架CTP 5的发布,并建立一个简单的asp.net MVC的博客,我只是有两个表:帖子和评论。这是在POCO完全做到,我只需要在部分的DbContext,在那里我需要它是单元测试的帮助(使用IDbSet?),我需要添加,更新,删除,检索一个简单/通用存储库模式。任何帮助是AP preciated。

I'm playing with the latest Entity Framework CTP 5 release and building a simple asp.net MVC blog where I just have two tables: Post and Comments. This is done entirely in POCO, I just need help on the DbContext part, where I need it to be unit testable (using IDbSet?) and I need a simple/generic repository pattern for add, update, delete, retrieval. Any help is appreciated.

感谢。

推荐答案

开始与你的DbContext,创建一个名为Database.cs新文件:

Start with you DbContext, create a new file called Database.cs:

Database.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();
        }
}

定义一个IDatabaseFactory和DatabaseFactory实现它:

Define a IDatabaseFactory and implement it with 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();
        }
    }

一次性扩展方法:

Disposable extension method:

Disposable.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()
        {
        }
    }

现在,我们可以定义我们的IRepository和我们RepositoryBase

Now we can define our IRepository and our 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();
        }
    }

现在你可以创建你IPostRepository和PostRepository:

Now you can create your IPostRepository and PostRepository:

IPostRepository.cs

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

PostRepository.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);
            }
        }

最后,UOW:

IUnitOfWork.cs

public interface IUnitOfWork
{
    void Commit();
}

UnitOfWork.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();
}

是在你的控制器:

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();
        }

您将需要使用IoC容器像StructureMap,使这项工作。您可以通过安装的NuGet结构图,或者如果你正在使用MVC 3,可以安装StructureMap-MVC的NuGet包。 (以下链接)

You will need to use an IoC container like StructureMap to make this work. You can install structure map via NuGet, or if you are using MVC 3, you can install the StructureMap-MVC NuGet package. (Links Below)

安装封装StructureMap.MVC4

安装封装StructureMap.MVC3

安装封装Structuremap

如果您有问题,只是让我知道。希望它帮助。

If you have questions just let me know. Hope it helps.

这篇关于实体框架4 CTP 4/5 CTP通用存储库模式和单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆