小弟工作過2家小作坊!項目經理使用的框架都是基於EF的Repository(倉儲)設計模式,我想說這種模式根本就是錯誤的使用! 更可怕的是博客園裡面也有很多這種教程!
之所以說錯誤的!是因為EF本身就是Repository(倉儲)的設計! 何必再套一層包裹給自己找事?而且也套的丑陋無比! 讓我們先來看下Repository的代碼思想!
下面的代碼將對實體的公共操作部分,提取為IRepository接口,比如常見的CRUD方法
public interface IRepository<T> where T : class { IEnumerable<T> FindAll(Func<T, bool> exp); void Add(T entity); void Delete(T entity); void Update(T entity); }
然後再泛型的類來具體實現上面的接口的方法。
1 public class Repository<T> : IRepository<T> where T:class 2 { 3 public DataContext context; 4 5 public Repository(DataContext context) 6 { 7 this.context = context; 8 } 9 public IEnumerable<T> FindAll(Func<T, bool> exp) 10 { 11 return context.GetTable<T>().Where(exp); 12 } 13 public void Add(T entity) 14 { 15 context.GetTable<T>().InsertOnSubmit(entity); 16 } 17 public void Delete(T entity) 18 { 19 context.GetTable<T>().DeleteOnSubmit(entity); 20 } 21 public void Update() 22 { 23 context.SubmitChanges(); 24 } 25 26 }
然後再在BLL業務層 通過依賴注入調用這個Repository對象進行 插入 刪除!等操作 我上面只簡單的實現了CRUD!如果要更多接口我還得去套!這是何必呢?何苦呢?EF本身就是實現了倉庫的模式!
我相信這裡會有人說 "使用該模式的最大好處就是將領域模型代碼和數據映射層之間解耦出來。",但是你完全可以使用一個接口啊!也能實現解耦啊!
interface IDbProvide { //返回db服務模型 DbContext GetDb(); } //實現接口 public class ModelContext : DbContext, IDbProvide { public ModelContext() : base("name=DefaultContext") { Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ModelContext>()); } DbContext IDbProvide.GetDb() { return this; } }
這樣我在BLL層 依然能通過依賴注入來解耦業務邏輯和數據映射層啊!
//關於學生的業務 public class StudentBll : IStudentBll { IDbProvide IDal { get; set; } public StudentBll() { //依賴注入 業務邏輯層不具體依賴於數據層 IDal = IocDal< IDbProvide>.Provide; } //獲取最高分數的同學 public Student CalculateScroebyTop01() { var stus = IDal.GetDb().OrderByDescending(s=>s.TotalScore).First(); return stus.OrderByDescending(s=>s.TotalScore).First(); } }
不服來辯!