Asp.net-Mvc-2
Entity Framework 4 CTP 4 / CTP 5 通用儲存庫模式和單元可測試
我正在使用最新的 Entity Framework CTP 5 版本並建構一個簡單的 asp.net MVC 部落格,其中只有兩個表:Post 和 Comments。這完全在 POCO 中完成,我只需要 DbContext 部分的幫助,我需要它可以進行單元測試(使用 IDbSet?),並且我需要一個簡單/通用的儲存庫模式來添加、更新、刪除、檢索。任何幫助表示讚賞。
謝謝。
從你的 DbContext 開始,創建一個名為 Database.cs 的新文件:
數據庫.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(); }數據庫工廠.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(); } }一次性擴展方法:
一次性用品.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(); } }現在您可以創建您的 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 包。(以下連結)
如果您有任何問題,請告訴我。希望能幫助到你。