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

Posted 260250932

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分享基于EF+WCF的通用三层架构及解析相关的知识,希望对你有一定的参考价值。

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

1. 项目架构图:

 

2. 项目解决方案:

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

   

3. Wcf Service的实现:

  • 工厂实现了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的实现:

 

  • 通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调,将领域模型从客户代码和数据映射层之间解耦出来,具体实现代码:
  1. View Code   
  2.  public class DaoBase : IRepository, IDisposable  
  3.      {  
  4.          public DbContext context;  
  5.    
  6.          public DaoBase()  
  7.          {  
  8.              this.context = new EasyEF.DAL.DbContext();  
  9.          }  
  10.    
  11.          public T Update<T>(T entity) where T : class 
  12.          {  
  13.              var set = context.Set<T>();  
  14.              set.Attach(entity);  
  15.              context.Entry<T>(entity).State = EntityState.Modified;  
  16.              context.SaveChanges();  
  17.    
  18.              return entity;  
  19.          }  
  20.    
  21.          public T Insert<T>(T entity) where T : class 
  22.          {  
  23.              context.Set<T>().Add(entity);  
  24.              context.SaveChanges();  
  25.              return entity;  
  26.          }  
  27.    
  28.          public void Delete<T>(T entity) where T : class 
  29.          {  
  30.              context.Entry<T>(entity).State = EntityState.Deleted;  
  31.              context.SaveChanges();  
  32.          }  
  33.    
  34.          public T Find<T>(params object[] keyValues) where T : class 
  35.          {  
  36.              return context.Set<T>().Find(keyValues);  
  37.          }  
  38.    
  39.          public List<T> FindAll<T>(Expression<Func<T, bool>> conditions = null) where T : class 
  40.          {  
  41.              if (conditions == null)  
  42.                  return context.Set<T>().ToList();  
  43.              else 
  44.                  return context.Set<T>().Where(conditions).ToList();  
  45.          }  
  46.    
  47.          public PagedList<T> FindAllByPage<T, S>(Expression<Func<T, bool>> conditions, Expression<Func<T, S>> orderBy, int pageSize, int pageIndex) where T : class 
  48.          {  
  49.              var queryList = conditions == null ? context.Set<T>() : context.Set<T>().Where(conditions) as IQueryable<T>;  
  50.    
  51.              return queryList.OrderByDescending(orderBy).ToPagedList(pageIndex, pageSize);  
  52.          }  
  53.    
  54.          public void Dispose()  
  55.          {  
  56.              this.context.Dispose();  
  57.          } 

4. 数据层基于Entity Framwork code First:

DBContext

  1. View Code   
  2.  public class DbContext : System.Data.Entity.DbContext  
  3.      {  
  4.          public DbContext()  
  5.              : base("MyDbContext")  
  6.          {  
  7.              this.Configuration.ProxyCreationEnabled = false;  
  8.          }  
  9.            
  10.          public DbSet<Category> Categories { getset; }  
  11.          public DbSet<Product> Products { getset; }  
  12.      } 

Model Mapping

  1. View Code   
  2.  [Table("Product")]  
  3.      public partial class Product  
  4.      {  
  5.          public int Id { get; set; }  
  6.    
  7.          [StringLength(50)]  
  8.          [Required(ErrorMessage = "名称不能为空")]  
  9.          public string Name { get; set; }  
  10.    
  11.          public int Size { get; set; }  
  12.    
  13.          [StringLength(300)]  
  14.          public string PhotoUrl { get; set; }  
  15.    
  16.          public DateTime AddTime { get; set; }  
  17.    
  18.          public int CategoryId { get; set; }  
  19.          public virtual Category Category { get; set; }  
  20.      } 

5. 提供了MVC调用服务端分页的实例:

  • MVC调用Wcf客户代理请求分页数据集合
  1. public ActionResult Index(int pageIndex  = 1)  
  2.         {  
  3.             var products = this.Service.GetProducts(PageSize, pageIndex);  
  4.             return View(products);  
  5.         } 
  • MVC附加用户Context信息到服务端
  1. protected override void OnActionExecuting(ActionExecutingContext filterContext)  
  2.          {  
  3.              base.OnActionExecuting(filterContext);  
  4.              WCFContext.Current.Operater = new Operater(){Name = "guozili",Time = DateTime.Now,IP = Fetch.UserIp,};  
  5.          } 
  • BLL取出Context信息并调用数据层
  1. public PagedList<Product> GetProducts(int pageSize, int pageIndex, int categoryId = 0)  
  2.          {  
  3.              //Test WCFContext  
  4.              var context = WCFContext.Current.Operater;  
  5.              return this.dao.FindAllByPage<Product, int>(p => categoryId == 0 ? true : p.CategoryId == categoryId, p => p.Id, pageSize, pageIndex);  
  6.          } 
  • DAL调用通用的Repository接口
  1. public PagedList<T> FindAllByPage<T, S>(Expression<Func<T, bool>> conditions, Expression<Func<T, S>> orderBy, int pageSize, int pageIndex) where T : class 
  2.          {  
  3.              var queryList = conditions == null ? context.Set<T>() : context.Set<T>().Where(conditions) as IQueryable<T>;  
  4.    
  5.              return queryList.OrderByDescending(orderBy).ToPagedList(pageIndex, pageSize);  
  6.          } 

6. 最后提供源码下

http://files.cnblogs.com/guozili/EasyEF.rar

原文链接:http://www.cnblogs.com/guozili/archive/2012/09/03/2667429.html

以上是关于分享基于EF+WCF的通用三层架构及解析的主要内容,如果未能解决你的问题,请参考以下文章

三层架构解析

JavaWeb.12.三层架构项目集成

EF架构~终于自己架构了一个相对完整的EF方案

分享一个大型进销存供应链项目(多层架构分布式WCF多服务器部署微软企业库架构)

ASP.NET MVC 的三层架构 + EF数据模型

Volcano架构设计与原理介绍