求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
MVC+EF+架构设计
 

作者:天涯~ ,发布于2012-8-8

 

介于这段时间的学习,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就能起作用了~

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

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

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

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

对于这个分层是否过于复杂,个人并不是这么看的,至少这么分层,每个分层都有其中不可少的因素在里面。前期搭建好以后,也许项目真的发展起来后, 会有助于项目真正的开发。当然,如果是小项目,个人也觉得没有必要分太多层。

好了,现在说说,我们这个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.IBLL和CinDou.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.BLL和CinDou.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>
<

@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>


相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程

 
分享到
 
 
     


使用decj简化Web前端开发
Web开发框架形成之旅
更有效率的使用Visual Studio
MVP+WCF+三层结构搭建框架
ASP.NET运行机制浅析【图解】
编写更好的C#代码
10个Visual Studio开发调试技巧
更多...   


.NET框架与分布式应用架构设计
.NET & WPF & WCF应用开发
UML&.Net架构设计
COM组件开发
.Net应用开发
InstallShield


日照港 .NET Framework & WCF应用开发
神华信息 .NET单元测试
北京 .Net应用软件系统架构
台达电子 .NET程序设计与开发
赛门铁克 C#与.NET架构设计
广东核电 .Net应用系统架构
更多...