分享基于EF+WCF的通用三層架構(gòu)及解析
本項目結(jié)合EF 4.3及WCF實現(xiàn)了經(jīng)典三層架構(gòu),各層面向接口,WCF實現(xiàn)SOA,Repository封裝調(diào)用,在此基礎(chǔ)上實現(xiàn)了WCFContext,動態(tài)服務(wù)調(diào)用及一個分頁的實例。
1. 項目架構(gòu)圖:
2. 項目解決方案:
- 在傳統(tǒng)的三層架構(gòu)上增加了WcfService(服務(wù)端),WcfClientProxy(客戶端服務(wù)調(diào)用),及WcfExtension(一些擴展)
3. Wcf Service的實現(xiàn):
- 工廠實現(xiàn)了RemoteServiceFactory(用于遠(yuǎn)程調(diào)用)和RefServiceFactory(本地引用調(diào)用服務(wù)層)生成客戶端代理,都需要實現(xiàn)IServiceFactory的“IService CreateService();”
- RemoteServiceFactory通過ChannelFactory動態(tài)產(chǎn)生客戶端代理類IService,并將此對象進(jìn)行緩存
- WCFExtension實現(xiàn)了WCFContext,可傳輸用戶登陸或IP上下文信息,以及攔截方法寫Log的機制,具體可以參考 http://www.cnblogs.com/lovecindywang/archive/2012/03/01/2376144.html
3. 數(shù)據(jù)層Repository的實現(xiàn):
- 通過用來訪問領(lǐng)域?qū)ο蟮囊粋€類似集合的接口,在領(lǐng)域與數(shù)據(jù)映射層之間進(jìn)行協(xié)調(diào),將領(lǐng)域模型從客戶代碼和數(shù)據(jù)映射層之間解耦出來,具體實現(xiàn)代碼:
- View Code
- public class DaoBase : IRepository, IDisposable
- {
- public DbContext context;
- public DaoBase()
- {
- this.context = new EasyEF.DAL.DbContext();
- }
- public T Update<T>(T entity) where T : class
- {
- var set = context.Set<T>();
- set.Attach(entity);
- context.Entry<T>(entity).State = EntityState.Modified;
- context.SaveChanges();
- return entity;
- }
- public T Insert<T>(T entity) where T : class
- {
- context.Set<T>().Add(entity);
- context.SaveChanges();
- return entity;
- }
- public void Delete<T>(T entity) where T : class
- {
- context.Entry<T>(entity).State = EntityState.Deleted;
- context.SaveChanges();
- }
- public T Find<T>(params object[] keyValues) where T : class
- {
- return context.Set<T>().Find(keyValues);
- }
- public List<T> FindAll<T>(Expression<Func<T, bool>> conditions = null) where T : class
- {
- if (conditions == null)
- return context.Set<T>().ToList();
- else
- return context.Set<T>().Where(conditions).ToList();
- }
- public PagedList<T> FindAllByPage<T, S>(Expression<Func<T, bool>> conditions, Expression<Func<T, S>> orderBy, int pageSize, int pageIndex) where T : class
- {
- var queryList = conditions == null ? context.Set<T>() : context.Set<T>().Where(conditions) as IQueryable<T>;
- return queryList.OrderByDescending(orderBy).ToPagedList(pageIndex, pageSize);
- }
- public void Dispose()
- {
- this.context.Dispose();
- }
4. 數(shù)據(jù)層基于Entity Framwork code First:
DBContext
- View Code
- public class DbContext : System.Data.Entity.DbContext
- {
- public DbContext()
- : base("MyDbContext")
- {
- this.Configuration.ProxyCreationEnabled = false;
- }
- public DbSet<Category> Categories { get; set; }
- public DbSet<Product> Products { get; set; }
- }
Model Mapping
- View Code
- [Table("Product")]
- public partial class Product
- {
- public int Id { get; set; }
- [StringLength(50)]
- [Required(ErrorMessage = "名稱不能為空")]
- public string Name { get; set; }
- public int Size { get; set; }
- [StringLength(300)]
- public string PhotoUrl { get; set; }
- public DateTime AddTime { get; set; }
- public int CategoryId { get; set; }
- public virtual Category Category { get; set; }
- }
5. 提供了MVC調(diào)用服務(wù)端分頁的實例:
- MVC調(diào)用Wcf客戶代理請求分頁數(shù)據(jù)集合
- public ActionResult Index(int pageIndex = 1)
- {
- var products = this.Service.GetProducts(PageSize, pageIndex);
- return View(products);
- }
- MVC附加用戶Context信息到服務(wù)端
- protected override void OnActionExecuting(ActionExecutingContext filterContext)
- {
- base.OnActionExecuting(filterContext);
- WCFContext.Current.Operater = new Operater(){Name = "guozili",Time = DateTime.Now,IP = Fetch.UserIp,};
- }
- BLL取出Context信息并調(diào)用數(shù)據(jù)層
- public PagedList<Product> GetProducts(int pageSize, int pageIndex, int categoryId = 0)
- {
- //Test WCFContext
- var context = WCFContext.Current.Operater;
- return this.dao.FindAllByPage<Product, int>(p => categoryId == 0 ? true : p.CategoryId == categoryId, p => p.Id, pageSize, pageIndex);
- }
- DAL調(diào)用通用的Repository接口
- public PagedList<T> FindAllByPage<T, S>(Expression<Func<T, bool>> conditions, Expression<Func<T, S>> orderBy, int pageSize, int pageIndex) where T : class
- {
- var queryList = conditions == null ? context.Set<T>() : context.Set<T>().Where(conditions) as IQueryable<T>;
- return queryList.OrderByDescending(orderBy).ToPagedList(pageIndex, pageSize);
- }
6. 最后提供源碼下
http://files.cnblogs.com/guozili/EasyEF.rar
原文鏈接:http://www.cnblogs.com/guozili/archive/2012/09/03/2667429.html