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

     
    4. 数据层基于Entity Framwork code First:
    • DBContext
      View Code
       1 public class DbContext : System.Data.Entity.DbContext
       2     {
       3         public DbContext()
       4             : base("MyDbContext")
       5         {
       6             this.Configuration.ProxyCreationEnabled = false;
       7         }
       8         
       9         public DbSet<Category> Categories { getset; }
      10         public DbSet<Product> Products { getset; }
      11     }
    • Model Mapping
      View Code
       1 [Table("Product")]
       2     public partial class Product
       3     {
       4         public int Id { getset; }
       5 
       6         [StringLength(50)]
       7         [Required(ErrorMessage = "名称不能为空")]
       8         public string Name { getset; }
       9 
      10         public int Size { getset; }
      11 
      12         [StringLength(300)]
      13         public string PhotoUrl { getset; }
      14 
      15         public DateTime AddTime { getset; }
      16 
      17         public int CategoryId { getset; }
      18         public virtual Category Category { getset; }
      19     }

    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. 最后提供源码下载
    https://files.cnblogs.com/guozili/EasyEF.rar
  • 相关阅读:
    毕业四年,你赚回四年的花费了吗?
    【转】解决VS2008 开发Windows Mobile 项目生成速度慢的问题
    WinCE/Mobile上下滑动浏览DataGrid数据 【转】
    【转】取得汉字拼音的首字母
    漂亮的 Windows Mobile 按钮
    SQLite中的常用操作(总结)
    浅谈HTTP中Get与Post的区别
    Oracle学习之数组
    firefox与ie 的javascript区别
    常用bash shell 脚本
  • 原文地址:https://www.cnblogs.com/guozili/p/2667429.html
Copyright © 2011-2022 走看看