分享基于EF+WCF的通用三层架构及解析

本项目结合EF 4.3及WCF实现了经典三层架构,各层面向接口,WCF实现SOA,Repository封装调用,在此基础上实现了WCFContext,动态服务调用及一个分页的实例。

1. 项目架构图:

分享基于EF+WCF的通用三层架构及解析


2. 项目解决方案:

分享基于EF+WCF的通用三层架构及解析

  • 在传统的三层架构上增加了WcfService(服务端),WcfClientProxy(客户端服务调用),及WcfExtension(一些扩展)

3. Wcf Service的实现:

分享基于EF+WCF的通用三层架构及解析

  • 工厂实现了RemoteServiceFactory(用于远程调用)和RefServiceFactory(本地引用调用服务层)生成客户端代理,都需要实现IServiceFactory的“IService CreateService();”
  • RemoteServiceFactory通过ChannelFactory动态产生客户端代理类IService,并将此对象进行缓存
  • WCFExtension实现了WCFContext,可传输用户登陆或IP上下文信息,以及拦截方法写Log的机制,具体可以参考 http://www.cnblogs.com/lovecindywang/archive/2012/03/01/2376144.html

3. 数据层Repository的实现:

分享基于EF+WCF的通用三层架构及解析

  • 通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调,将领域模型从客户代码和数据映射层之间解耦出来,具体实现代码:
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. 数据层基于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调用服务端分页的实例:

  • MVC调用Wcf客户代理请求分页数据集合
public ActionResult Index(int pageIndex  = 1)  


        {  



            var products = this.Service.GetProducts(PageSize, pageIndex);  




            return View(products);  



        } 
  • MVC附加用户Context信息到服务端
protected override void OnActionExecuting(ActionExecutingContext filterContext)  


         {  


             base.OnActionExecuting(filterContext);  



             WCFContext.Current.Operater = new Operater(){Name = "guozili",Time = DateTime.Now,IP = Fetch.UserIp,};  



         } 
  • BLL取出Context信息并调用数据层
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调用通用的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. 最后提供源码下

相关推荐