【.Net码农】【MVC】MVC+EF+架构设计

http://www.cnblogs.com/imythu/archive/2012/06/09/mvc-ef-design.html

http://www.cnblogs.com/imythu/archive/2012/06/09/mvc-ef-design2.html

http://www.cnblogs.com/imythu/archive/2012/06/11/mvc-ef-design3.html



介于这段时间的学习,MVC 和 Entity Framework 再加上自己对框架这部分的理解,弄了这么个Demo,希望大家能给点意见,一起讨论讨论。本章中没有多么高深的理论知识,只是个人对于架构的理解,加上MVC 和 EntityFramework,可以说是个整体的部分

先贴下我的项目的分布图:

整个项目主要采用三层架构,面向接口的编程方式。

界面层:User Interface  

CinDou.Web主要放我们的Web页面,

CinDou.Route主要放置MVC中Controller,

这里我采用把Controller分离出来。个人考虑的原因是:项目比较清晰,职责比较单一。

逻辑层:Business Logic Layer  

CinDou.BFactory 是逻辑工厂层,用于创建逻辑层的接口,便于界面层调用。

CinDou.IBLL 逻辑接口层

CinDou.BLL 逻辑业务层 主要负责逻辑层中的业务。

CinDou.Model 逻辑业务类

数据库层:Data Accss Layer

CinDou.DFacoty:数据工厂层,用于创建数据库层的接口,从而让逻辑层调用

CinDou.IDAL : 数据库接口层

CinDou.DAL : 数据库持久层

CinDou.EFramework: Entity Framework层

工具层:ToolKit

CinDou.Tools 常用的工具类方法层

Component :控件层

 

大概的一个分层是这个样子的。其实园子里有很多同学都说过这个话题,每个人对分层有各自的看法,不过看了很多文章,总感觉有点语曰不详,或者可能是我没有找到,所以个人自己写个,希望有兴趣的同学们一起讨论下。


貌似MVC现在比较热闹,所以,在这个项目中我也采取了MVC,但是MVC的Controller总是包含在站点文件夹中,这个总让我很不爽,至于为什么不爽,个人总感觉Controller是个页面的逻辑部分,一般在以前我们总放在aspx.cs文件中,但是mvc没有这个aspx.cs文件,所以,索性我们把这部分单独出来建立了CinDou.Route这个项目

为了使这个Controller能单独出来,我们必须还要做一些其它的工作:

Step1:在CinDou.Tools中建立

IRegisterRoutes.cs

using  System.Web.Routing;
 
namespace  CinDou.Tools
{
     interface  IRegisterRoutes
     {
         void  RegisterRoutes(RouteCollection Routes);
     }
}

CinDouRoutes.cs

using  System.Web.Routing;
using  System.Web.Mvc;
 
namespace  CinDou.Tools
{
     class  CinDouRoutes : IRegisterRoutes
     {
         public  void  RegisterRoutes(RouteCollection routes)
         {
             routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
             routes.MapRoute(
                 "Default" , // Route name
                 "{controller}/{action}/{id}" , // URL with parameters
                 new  { controller = "Home" , action = "Index" , id = UrlParameter.Optional } // Parameter defaults
             );
         }
     }
}

CinDouApplication.cs

using  System.Web;
using  System.Web.Mvc;
using  System.Web.Routing;
 
namespace  CinDou.Tools
{
     public  class  CinDouApplication : HttpApplication
     {
         protected  void  Application_Start()
         {
             CinDouRoutes pdr = new  CinDouRoutes();
             AreaRegistration.RegisterAllAreas();
             pdr.RegisterRoutes(RouteTable.Routes);
         }
     }
}

我们在CinDou.Tools中建立好这三个文件后,然后在CinDou.Web中引用这个Dll即可。 同时,我们修改Global.asax文件使其指向我们刚刚建立的CinDouApplication文件。右键点击Global.asax文件,点"查看标记”然后修改为:

<%@ Application Inherits="CinDou.Tools.CinDouApplication" Language="C#" %>


我们在CinDou.Route中创建创建的ProductController就能起作用了~



发了前面两篇文章后,有的同学说:“分层应该依项目而定,没有什么最好的分层,只有最合适的。” 也有同学说 “分层太复杂,才多大的项目”

在这里我想发表下我的看法,个人之言,权当讨论的话题:首先说分层应该依项目而定,这话总体来说没有错误,但是到底什么样的项目该用什么样的分层

这个没有定数,至少我还不知道这个确切的分界线~况且,我们现在可能做个小项目,到以后也许慢慢发展起来怎么办?

对于这个分层是否过于复杂,个人并不是这么看的,至少这么分层,每个分层都有其中不可少的因素在里面。前期搭建好以后,也许项目真的发展起来后,

会有助于项目真正的开发。当然,如果是小项目,个人也觉得没有必要分太多层。

好了,现在说说,我们这个EF的底层框架怎么搭建。

首先 我们现在数据库建一个表 Product    表结构如下:

CinDou.EFramework层中建立 CinDouDbContext.cs 文件,代码如下

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration.Conventions;
using CinDou.Tools;
using CinDou.Model;
 
namespace CinDou.EFramework
{
     string connection= "xxxxx" ; //数据库链接
 
     public class CinDouDbContext : DbContext
     {
         public AppedDbContext()
             : base(connection)
         { }
 
          public DbSet<Product> Products{get; set;}
 
          protected override void OnModelCreating(DbModelBuilder modelBuilder)
          {
              modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//移除复数表名的契约
 
              modelBuilder.Conventions.Remove<IncludeMetadataConvention>();//防止黑幕交易 要不然每次都要访问 EdmMetadata这个表
          }
     }
}

  

在 CinDou.Model 项目中建立 Product.cs

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.ComponentModel.DataAnnotations;
 
namespace  CinDou.Model
{
     public  class  Product
     {
         public  int  ID { get ; set ; }
 
         [Column( "Name" )]
         public  string  ProductName { get ; set ; }
 
         [Column( "Price" )]
         public  decimal  ProductPrice { get ; set ; }
 
         public  DateTime CreateDate { get ; set ; }
     }
}

  

在BFactoy和DFactory层中分别建立BLLFactory。cs 和 DALFactory.cs

using  System;
using  System.Collections.Generic;
using  System.Reflection;
using  System.Linq;
using  System.Text;
using  CinDou.Tools;
using  CinDou.IBLL;
using  CinDou.BLL;
 
namespace  CinDou.BFactory
{
     public  sealed  class  BLLFactory
     {
         static  string  bllLayer = WebSite.BLLAssembly;
 
         public  static  CinDou.IBLL.IProduct CreateProduct()
         {
             return  (CinDou.IBLL.IProduct)Assembly.Load(bllLayer).CreateInstance(bllLayer + ".Product" );
         }
     }
}

  

using  System.Reflection;
using  CinDou.Tools;
using  CinDou.IDAL;
using  CinDou.DAL;
 
namespace  CinDou.DFactory
{
     public  sealed  class  DALFactory
     {
         static  string  dalLayer = WebSite.DALAssembly;
 
         public  static  CinDou.IDAL.IProduct CreateProduct()
         {
             return  (CinDou.IDAL.IProduct)Assembly.Load(dalLayer).CreateInstance(dalLayer + ".Product" );
         }
     }
}

  

这里,我们使用了反射和工厂模式。这样便于解耦和层的封闭

CinDou.IBLLCinDou.IDAL中分别建立IProduct.cs文件

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  CinDou.Model;
 
namespace  CinDou.IBLL
{
     public  interface  IProduct
     {
         bool  Add(CinDou.Model.Product product);
 
         IEnumerable<CinDou.Model.Product> List();
     }
}

  

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  CinDou.Model;
 
namespace  CinDou.IDAL
{
     public  interface  IProduct
     {
         bool  Add(Product product);
 
         IEnumerable<Product> List();
     }
}

  

然后再在CinDou.BLLCinDou.DAL中建立Product.cs

 

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  CinDou.IBLL;
using  CinDou.DFactory;
using  CinDou.IDAL;
using  CinDou.DAL;
using  CinDou.Model;
 
namespace  CinDou.BLL
{
     public  class  Product : CinDou.IBLL.IProduct
     {
         public  bool  Add(CinDou.Model.Product product)
         {
             return  CinDou.DFactory.DALFactory.CreateProduct().Add(product);
         }
       
         public  IEnumerable<CinDou.Model.Product> List()
         {
             return  CinDou.DFactory.DALFactory.CreateProduct().List();
         }
     }
}

 

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Data.Entity;
using  CinDou.IDAL;
using  CinDou.EFramework;
using  CinDou.Model;
using  CinDou.Tools;
 
namespace  CinDou.DAL
{
     public  class  Product : CinDou.IDAL.IProduct
     {
         private  CinDouDbContext CinDouDB = new  CinDouDbContext;
      
 
         public  bool  Add(CinDou.Model.Product product)
         {
             bool  flag = false ;
 
             try
             {
                 CinDouDB.Products.Add(product);
 
                 CinDouDB.SaveChanges();
 
                 flag = true ;
             }
             catch { }
 
             return  flag;
         }
 
         public  IEnumerable<CinDou.Model.Product> List()
         {
             return  CinDouDBProducts.ToList();
         }
     }
}

  

 我们再在CinDou.Route项目中建立 Controllers文件夹,然后建立ProductController.cs文件

 

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Web.Mvc;
using  CinDou.IBLL;
using  CinDou.BFactory;
 
namespace  CinDou.Route.Controllers
{
 
     public  class  ProductController : Controller
     {
         public  ViewResult Index()
         {
            
             return  View(CinDou.BFactory.BLLFactory.CreateProduct().List());
         }
 
         public  ActionResult Create()
         {
             return  View( new  CinDou.Model.Product());
         }
 
         //
         // POST: /Department/Create
         [HttpPost]
         public  ActionResult Create(CinDou.Model.Product product)
         {
             bool  flag = CinDou.BFactory.BLLFactory.CreateProduct().Add(product);
 
             return  RedirectToAction( "Index" );
         }
     }
}

  

 在CinDou.Web项目中的Views文件夹下建立Product文件夹,在里面建立Index.cshtml文件

在建立的时候,借助vs的智能感应,能非常方便的建立index.cshtml文件中的内容。

@model IEnumerable< CinDou.Model.Product >
 
< p >
     @Html.ActionLink("Create New", "Create")
</ p >
< table >
     < tr >
         < th >
             ProductName
         </ th >
         < th >
             ProductPrice
         </ th >
         < th >
             CreateDate
         </ th >
         < th ></ th >
     </ tr >
 
@foreach (var item in Model) {
     < tr >
         < td >
             @Html.DisplayFor(modelItem => item.ProductName)
         </ td >
         < td >
             @Html.DisplayFor(modelItem => item.ProductPrice)
         </ td >
         < td >
             @Html.DisplayFor(modelItem => item.CreateDate)
         </ td >
         < td >
             @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
             @Html.ActionLink("Details", "Details", new { id=item.ID }) |
             @Html.ActionLink("Delete", "Delete", new { id=item.ID })
         </ td >
     </ tr >
}
 
</ table >

  项目至此,已经差不多建立完整了。最后再附上我的源码。便于理解吧~

 

Download

 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值