MVC模块化架构

全面解析ASP.NET MVC模块化架构方案

什么叫架构?揭开架构神秘的面纱,无非就是:分层+模块化。任意复杂的架构,你也会发现架构师也就做了这两件事。

本文将会全面的介绍我们团队在模块化设计方面取得的经验。之所以加了“全面”二字,是因为本文的内容将会涉及到:数据库、路由、C#、JavaScript、CSS、HTML等一个完整模块所需要的内容。

在阅读本文之前后,你也可以转到我们的开源项目:https://github.com/leotsai/mvcsolution。这个开源项目完整的总结了我们团队在ASP.NET MVC领域的分层架构思想,同时也定义了很多标准。

本文的目的则主要是介绍架构思想之模块化。

当前项目架构以及模块化架构图

一个模块的运行通常要依托于一个完整的系统。在本文的例子中,模块化依托于我们的开源项目MvcSolution这个架构。下面先看看这个架构的工程引用关系图:

上面这个架构是系统原本的架构,而在这个原本的架构之上,我们怎么添加模块的呢?请看下图:

从上图可以看出,我们增加的模块是引用了系统原来的多个工程的,这虽然会增加模块与当前系统的耦合度,但是却让模块的开发变得简单很多。而对于我们团队来讲,因为所有项目都是基于MvcSolution这个架构,所以每一个模块都可以很快的融入每一个系统。

下面在看看添加了模块之后的项目文件结构:

由于我们这个模块不算大,所以就把所有C#文件都放到一个工程里面了,分层只在心中。这也有利于我们将这个模块搬运到其他项目中。

1. 模块的入口

我们模块的入口非常简单,没有反射,也没有动态初始化,就是一个再普通不过的System.Web.MvcAreaRegistration。 在Global.ascx.cs文件中,通过AreaRegistration.RegisterAllAreas();把所有引用的Area全部注册。

在这个AreaRegistration类中,主要完成了路由的注册以及IOC的注册,如下图:

这样,这个模块的公开URL地址就已经生成了,如:http://www.example.com/donating。你可以在程序其他地方添加这个链接,那么用户就可以访问这个模块了。

2. 模块化之数据访问

模块内的数据访问如何跟现有系统的数据访问共存,这个问题是所有模块化架构师最难处理的问题,相比其他文件(C#、JS、CSS、HTML),数据访问最难处理好,因为下面这个目标很难达到:

目标:模块内可以很轻易的访问现有数据库的所有内容,但是却最好不对现有数据库进行任何更改,只有这样,当该模块移除之后,才不会留下任何无用的代码;

在我们的实践当中,基本上可以达到这个目标。下面我就详细介绍我们是如何进行数据访问设计的,基于EF CodeFirst。

原有系统使用着一个非常复杂且庞大的数据库,我们希望新增加的模块不做任何更改。原有数据库大概长这个样子的:

我们增加的模块化工程的文件结构如下图:

我们是增加了一个新的数据库DonatingDataContext,当然,这个数据库继承自原有系统的数据库。这样,新增加的模块就可以完全访问原有数据库了。请看模块数据库代码:

 

上方代码请注意 base.OnModelCreating(modelBuilder); 这句话非常重要,干什么的就不用解释了。

在增加新模块才用到的表的时候,难免需要跟原有系统的表建立外键关系。正常的做法,我们是通过EntityTypeConfiguration<T>来添加,如下图:

但是在模块化设计中,由于不能修改原有系统中表的定义,所以用EntityTypeConfiguration<T>是无法完成外键关系定义的。这时,只能用DataAnnotations的方式:

public Guid CreatorUserId { get; set; }

[ForeignKey("CreatorUserId")]
public virtual User CreatorUser { get; set; }

这样,在新数据库中,就可以随意的访问原有数据库了。如下所示:

1 public DonatePost GetPost(Guid postId)
2 {
3     using (var db = new DonatingDataContext())
4     {
5         return db.DonatePosts.Get(postId);
6     }
7 }

而在发布到产品服务器的时候,只需要在产品数据库上执行新模块的SQL脚本即可(可以通过EF生成新库,再用ManagementStudio生成脚本)。

3. 模块化之静态文件(JS、CSS、HTML)

从本文最开始的文件结构图中可以看到,我们把几乎所有静态文件都放到了一个叫“Plugins/Donating”的文件夹中了,这将非常有利于我们搬运这个模块到其他项目中。

请注意上面段落中的“几乎”二字,这说明还有小部分文件不在这里。这部分特殊的文件都是JS,有两部分,一部分在“_js-plugins/donating”,另一部分在“_grunt/gruntfile.js”中。用过grunt的都知道,这是JS未压缩为混淆的源文件了,你也可以参考我们的开源项目MvcSolution 了解更多这两部分JS的设计思想。简单的将,这两部分JS在发布网站的时候,是要被删除的,不需要拷贝到服务器的。

下面,请看静态文件结构图:

上图说明了很多东西,除了js文件夹是由grunt生成的话,其他的都一目了然,不再赘述。

对于CSHTML文件,在我们的例子中,是引用的原有项目的一个Layout,包括一些基本的CSS和JS,都有引用原有项目。这固然增加了耦合度,但我们的项目都是基于同一个架构,各个层级的代码都在标准之内,所以还是可以很容易的搬运模块的。

好了,本文关于ASP.NET MVC模块化的介绍就完了,不知道你是否看的云里雾里的。没有关系,当你决定开始尝试一下模块化设计的时候,相信本文中的一些实践还是能给你一些启发的。

最后

希望大家针对本文中的观点和实践畅所欲言,说说你的看法。

时间: 2024-10-03 23:27:08

MVC模块化架构的相关文章

全面解析ASP.NET MVC模块化架构方案

什么叫架构?揭开架构神秘的面纱,无非就是:分层+模块化.任意复杂的架构,你也会发现架构师也就做了这两件事. 本文将会全面的介绍我们团队在模块化设计方面取得的经验.之所以加了“全面”二字,是因为本文的内容将会涉及到:数据库.路由.C#.JavaScript.CSS.HTML等一个完整模块所需要的内容. 在阅读本文之前后,你也可以转到我们的开源项目:https://github.com/leotsai/mvcsolution.这个开源项目完整的总结了我们团队在ASP.NET MVC领域的分层架构思想

Angular JS从入门基础 mvc三层架构 常用指令

Angular JS从入门基础  mvc模型 常用指令 ★ 最近一直在复习AngularJS,它是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJS有着诸多特性,最为核心的是:MVC.模块化.自动化双向数据绑定.语义化标签.依赖注入等等. 1.常用指令 AngularJS 通过指令扩展了HTML,且通过表达式绑定数据到 HTML.下面我们看一下AngularJS中的常用指令. (1).基本概念 指令:AngularJS中,通过扩展HTML的属性提供功能.所以,ng-

[转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

本文转自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html 〇.目录 一.前言 二.工具准备 三.T4代码生成预热 (一) 单文件生成:HelloWorld.cs (二) 多文件生成 四.生成数据层实体相关相似代码 (一) 生成准备 (二) 生成实体相关相似代码 生成实体映射配置类 生成实体仓储接口 生成实体仓储实现 五.源码获取 系列导航 一.前言 经过前面EF的<第一篇>与<第二篇>,我们的数据层功能已经较为完善了,但有不少

微信Android模块化架构重构实践

微信Android架构历史 微信Android诞生之初,用的是常见的分层结构设计.这种架构简单.清晰并一直沿袭至今.这是微信架构的v1.x时代. 图1-架构演进 到了微信架构的v2.x时代,随着业务的快速发展,消息通知不及时和Android 2.3版本之前webview内存泄露问题开始突显.由于代码.内存.apk大小都在增长,对系统资源的占用越来越多,导致微信进程容易被系统回收.因此微信开始转向多进程架构,独立的通信进程保持长连接的稳定性,独立的webview进程也阻隔了内存泄露导致的问题. 时

asp.net mvc应用架构的思考--Unity的应用及三层代码

最近要做一个项目,和国外的架构师聊过之后.对方提到了他准备采用asp.net mvc, jquery, Unity 等技术来代替老的技术: 如asp.net web form. 他请我帮他想一些关于架构的东西.一直以来,关于asp.net mvc应用的架构,有一些想法.正好借这个机会写出来.资深的人士可能已经知道了,就当是复习吧.欢迎发表意见.指出不足. Unity的应用 Unity出来已经有几年了.早几年的1.2版就可以实现这里所说的功能.目前最新稳定版是2.1.正在开发的3.0也许会给我们带

MVC实用架构设计(三)——EF-Code First(1):Repository,UnitOfWork,DbContext

前言 终于到EF了,实在不好意思,最近有点忙,本篇离上一篇发布已经一个多星期了,工作中的小迭代告一段落,终于有点时间来继续我们的架构设计了,在这里先对大家表示歉意. 其实这段时间我并不是把这个系列给忘记了,而是一直在思考,想着接下来应该怎么写.因为园子里已经有很多非常优秀的EF的文章了,比如: Entity Framework Code First 学习日记 [译著]Code First :使用Entity. Framework编程 Entity Framework技术系列 EF框架step b

Hibernate之struts2整合hibernate以及MVC分层架构的使用

 一.学习案例:通过实现会员注册功能整合struts2和hibernate,同时了解hibernate的API的使用. 二.案例分析:这章主要是MVC分层架构以及struts2和hibernate的整合思路.代码请查看演示项目. a)这次的演示项目使用了MVC分层架构.大家一定要下载演示项目进行分析. b)导入struts2和hibernate所需要的jar包 c)创建struts.xml和hibernate.cfg.xml d)在web.xml配置struts2 e)创建注册页面(regi

ASP.NET MVC模块化开发——动态挂载外部项目

原文:ASP.NET MVC模块化开发--动态挂载外部项目 最近在开发一个MVC框架,开发过程中考虑到以后开发依托于框架的项目,为了框架的维护更新升级,代码肯定要和具体的业务工程分割开来,所以需要解决业务工程挂载在框架工程的问题,MVC与传统的ASP.NET不同,WebForm项目只需要挂在虚拟目录拷贝dll就可以访问,但是MVC不可能去引用工程项目的dll重新编译,从而产生了开发一个动态挂在MVC项目功能的想法,MVC项目挂载主要有几个问题,接下来进行详细的分析与完成解决方案 一般动态加载dl

Mvc 模块化开发

在Mvc中,标准的模块化开发方式是使用Areas,每一个Area都可以注册自己的路由,使用自己的控件器与视图.但是在具体使用上它有如下两个限制 1.必须把视图文件放到主项目的Areas文件夹下才能生效,否则运行时会发生找不到视图的错误. 2.在实际开发中,这种开发方式只能建立一个项目,所有的开发工作都在这个项目里完成,非常不利于团队大规模开发. 显然,上面的两点限制严重制约了插件化开发实际运用.为了实现真正的插件化开发,大家积极的思考研究,又找到了如下几种方式 1.MVC Portable Ar