entity framework4 CTP 4 / CTP 5通用存储库模式和单元可testing
我正在玩最新的entity frameworkCTP 5版本,并build立一个简单的asp.net MVC博客,我只有两个表:发表和评论。 这完全在POCO中完成,我只需要DbContext部分的帮助,我需要它是unit testing(使用IDbSet?),我需要一个简单/通用的存储库模式来添加,更新,删除,检索。 任何帮助表示赞赏。
谢谢。
从DbContext开始,创build一个名为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实现它:
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.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
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(); } }
现在你可以创build你的IPostRepository和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(); }
您将需要使用像StructureMap这样的IoC容器来完成这个工作。 您可以通过NuGet安装结构图,或者如果您使用的是MVC 3,则可以安装StructureMap-MVC NuGet包。 (下面的链接)
安装程序包StructureMap.MVC4
安装程序包StructureMap.MVC3
安装包结构图
如果您有任何问题,请告诉我。 希望它有帮助。
我只是喜欢这个关于entity framework4 POCO,存储库和规范模式的深入文章
http://huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern/
我唯一不同的做法是在实现中,即在服务层中公开IPostRepository,并在控制器中有一个types为IPostService的接口字段,作为另一个抽象层,否则这是一个很好的例子 – 好的,Paul 。