基于asp.net的Web开发架构探索
问题由来
最近在研究适合团队开发的web架构解决方案,该架构即要适合分工协作又要有一定扩展性,适合不同的数据库需要,因此我查阅了一些资料,初步构想出了一套架构,请各位多多指教。
探索
web开发架构最经典莫过于三层架构,表示层、逻辑层、数据处理层。
数据访问层:其功能主要是负责数据库的访问。
业务逻辑层:是整个系统的核心,它与这个系统的业务(领域)有关。
表示层:是系统的UI部分,负责使用者与整个系统的交互。理想的状态是表示层不应包括系统的业务逻辑。
这些是经典的解释,如果要适合不同的数据库则需要加入工厂模式,里面用面向接口的方式进行多态调用。是不是这有点像petshop了。所以架构的初步设想是这样:
下面以获取用户信息为例,简述这个架构的流程:(以下为类似petshop的经典做法,了解的可以略过)
step 1 、首先我们应该建立项目所需的实体模型,在这里新建用户信息的实体模式,UserInfo.cs。该类保存在Model项目里。
step 2 、我们再将项目的单元功能写到相关的接口中,这里以获取用户信息功能为例。在IDAL项目里新建IUser接口。
//根据用户ID获取用户信息
UserInfo GetUserById(int userId);
step 3、完成了接口,我们就要实现它,现在我们用sqlserver、oracle两种数据库访问方式来实现它。以下是SqlserverDAL中User类对接口的现实:
public class User:IUser
{
public UserInfo GetUserById(int userId)
{
//实现操作
}
}
OracleDAL中现实方式类似。。。。
step 4、在此数据库访问层应该就基本写好了,下面应该给逻辑层调用了,但是两种实现方式怎么调用呢,或者说怎么有选择的调用它呢,petshop是这样处理的,在DALFactory中的DataAccess类,利用反射载入程序集从而实例化所需要的类:
private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];
public static IUser CreateUser()
{
string className = path + ".User";
return (IUser)Assembly.Load(path).CreateInstance(className);
}
至于要选择哪个数据库访问层,在配置文件里配置一下WebDAL。如:<add key="WebDAL" value="SQLServerDAL"/>。
这样就基本解决了逻辑层和数据访问层的耦合。
step 5、下面就该写逻辑层了,在BLL里面创建User.cs类。大致如下:
public class User
{
private static readonly IUser dal = DALFactory.DataAccess.CreateUser();
public UserInfo GetUserInfo(int userId) {
return dal.GetUserById(userId);
}
}
是不是觉得BLL毫无意义,因为它只是对数据访问层方法的简单调用,但并不是这样的,这里只有一个简单的事例,在实际项目中一个BLL里面处理的可能是一个非常复杂的逻辑,而这个复杂逻辑的结果才提供给表示层显示。
step 6、最后是表示层,好像没什么可说的,把从BLL取出来的数据绑定到你的页面就行了。
以上是仿petshop的架构设计,看起来没什么质疑的地方,毕竟是微软的经典案例。你可能抱怨的地方有两点,一是层是不是有点多,关系过于复杂;二如果我需要改变或增加一个数据库字段,那不是会很痛苦,因为要节联修改。这两个问题,我都没办法解决,一如果说过于层过于多而繁琐,那么下面我写的好像更为复杂,原谅。。。。二、鄙人觉得凡是分层开发,只要以数据库字段为依据的建立实体模型,都会存在节联修改的问题。除非全部用DataTable,那么在BLL、表示层调用的时候并不知道DataTable到底装有什么,这样无疑更加了调用的不便利。关于减少节联修改的问题,如有解决方法的请指教。
对以上架构的修改
我重点分析了以上架构的数据访问工厂的设计部分,即DALFactory中的DataAccess类。在此类中,实现了对不同数据库访问层的调用
。但如果现在有一个项目,里面有sqlserver又有oracle的现实,我们是不是要这样做:
private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];//对sqlserver数据库访问层的调用
private static readonly string path2 = ConfigurationManager.AppSettings["WebDAL2"];//对oracel数据库访问层的调用
public static IUser CreateUser()
{
string className = path + ".User";
return (IUser)Assembly.Load(path).CreateInstance(className);
}
public static IOrder CreateOrder()
{
string className = path2 + ".Order";
return (IUser)Assembly.Load(path2).CreateInstance(className);
}
如果要创建其他的访问类,我们还要写CreateProduct(),CreateArticle,CreateMenu。。。。。那么这样的类会很繁琐,我们能不能
只做一个方法,其他的工作只需要开发人员通过配置文件来完成呢。我的解决方案有两个:
一、Spring.net
这个东西就是专门用来解耦合的,我们将它的相关程序集加载到DALFactory中,于是在DataAccess中,我们可以做:
private static readonly string configPath = HttpContext.Current.Request.PhysicalApplicationPath +
ConfigurationManager.AppSettings["objectconfig"];//这是spring.net的对象配置文件在服务器上的物理位置
public static T CreateObject<T>()
{
IResource rs = new FileSystemResource(configPath);
IObjectFactory factory = new XmlObjectFactory(rs);
string id = typeof(T).FullName;
return (T)factory.GetObject(id);
}
这里我们传入一个泛型,让spring.net在它的对象配置文件里面找到该类型的程序集并加载,创建出对应的对象。objectconfig文件
大致如下:
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.net
http://www.springframework.net/xsd/spring-objects.xsd">
<object id="IDAL.IUser" type="SQLServerDAL.Function"></object>
</objects>
这样在BLL 就这样调用
private static readonly IUser dal = EtourAF.Shared.DALFactory.DataAccess.CreateObject<IUser>();
这样开发人员如果要加入一个对象就在object-config中加一段相关配置就行了。嘿嘿,这就变成了petshop+spring.net了,YY无极限。。。。
二、也是用反射
这里我们只是用了一个键值对的方式,照例在配置文件里配置相应的接口和对象,只是我们把他配置到了web.config当中:
<add key="IDAL.IUser" value="SQLServerDAL.Function" />
在DataAccess中,我们就这样写:
public static T CreateObject<T>()
{
string interfaceFullName = typeof(T).FullName;
string className = ConfigurationManager.AppSettings[interfaceFullName];
string nameSpace = className.Substring(0, className.LastIndexOf("."));
return (T)Assembly.Load(nameSpace).CreateInstance(className);
}
可能有人说
string nameSpace = className.Substring(0, className.LastIndexOf("."));
这里这个截取是不是觉得有点硬,我现在也只想到这个办法,但绝对不会有问题的。
好了,这些大概就是鄙人这两天的有些收获,请指教。
基于asp.net的Web开发架构探索的更多相关文章
- ASP.NET Core 企业级开发架构简介及框架汇总
企业开发框架包括垂直方向架构和水平方向架构.垂直方向架构是指一个应用程序的由下到上叠加多层的架构,同时这样的程序又叫整体式程序.水平方向架构是指将大应用分成若干小的应用实现系统功能的架构,同时这样的系 ...
- ASP.NET Core 企业级开发架构简介及框架汇总 (转载)
ASP.NET Core 企业开发架构概述 企业开发框架包括垂直方向架构和水平方向架构.垂直方向架构是指一个应用程序的由下到上叠加多层的架构,同时这样的程序又叫整体式程序.水平方向架构是指将大应用分成 ...
- 全 Javascript 的 Web 开发架构:MEAN
http://developer.51cto.com/art/201404/434759.htm 全 Javascript 的 Web 开发架构:MEAN 引言 最近在Angular社区的原型开发者间 ...
- ASP.NET Core Web开发学习笔记-1介绍篇
ASP.NET Core Web开发学习笔记-1介绍篇 给大家说声报歉,从2012年个人情感破裂的那一天,本人的51CTO,CnBlogs,Csdn,QQ,Weboo就再也没有更新过.踏实的生活(曾辞 ...
- 基于webpack的前端工程化开发解决方案探索(一):动态生成HTML(转)
1.什么是工程化开发 软件工程的工程化开发概念由来已久,但对于前端开发来说,我们没有像VS或者eclipse这样量身打造的IDE,因为在大多数人眼中,前端代码无需编译,因此只要一个浏览器来运行调试就行 ...
- 基于滴答清单 Web 开发的 PC 客户端
基于滴答清单 Web 开发的 PC 客户端 关于「滴答清单」 滴答清单是一款不可多得的 GTD 效率工具,它有着清晰明了的界面设计.恰到好处的功能设置.稳定的同步服务,如果你还缺少一款简洁而有效的 G ...
- Asp.Net Core Web应用程序—探索
前言 作为一个Windows系统下的开发者,我对于Core的使用机会几乎为0,但是考虑到微软的战略规划,我觉得,Core还是有先了解起来的必要. 因为,目前微软已经搞出了两个框架了,一个是Net标准( ...
- 基于ASP.NET 4.0开发的微商城系统OdnShop,开源发布
基于ASP.NET 4.0开发的开源微商城系统,我们的目标是构建一个核心完善而又轻量级的微商城平台,目前基本的核心功能,包括微信登陆/支付,产品管理,购物车与订单管理等,轻量级是为了更加便于理解源码和 ...
- 转: Orz是一个基于Ogre思想的游戏开发架构
Orz是一个基于Ogre思想的游戏开发架构,好的结构可以带来更多的功能.Orz和其他的商业以及非商业游戏开发架构不同.Orz更专著于开发者的感受,简化开发者工作.Orz可以用于集成其他Ogre3D之外 ...
随机推荐
- CUDA从入门到精通
http://blog.csdn.net/augusdi/article/details/12833235 CUDA从入门到精通(零):写在前面 在老板的要求下.本博主从2012年上高性能计算课程開始 ...
- 关于C++与Java中虚函数问题的读书笔记
之前一直用C++编程,对虚函数还是一些较为肤浅的理解.可近期由于某些原因搞了下Java,发现有些知识点不熟,于是站在先驱巨人的肩上谈谈C++与Java中虚函数问题. Java中的虚函数 以下是段别人的 ...
- C++ struct与class
1.相对于C中struct,C++做了很大的扩充.基本上和class 差不多.只有一些细节上的差别. 2.对于成员的默认访问权限,class是private,struct是public.需要注意的是, ...
- Uestc_suibian 暑假集训总结
唉,终于组队了,终于可以只BB了,我就BB,我就不上! 和Xiper以及chenxh组队了- 下面是总结: day1 第一天吃饱喝足,然后就上路了,我一开始就看到了C题大水题,但是我不敢想象这道题居然 ...
- hdu 5427 A problem of sorting 水题
A problem of sorting Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://bestcoder.hdu.edu.cn/contest ...
- delphi 插入表格HTML代码
<table width="174" height="76" border="1" align="center" ...
- delphi 使用进度条查看浏览器状态
使用进度条查看浏览器状态 procedure TForm1.WebBrowser1ProgressChange(ASender: TObject; Progress, ProgressMax ...
- 三分钟掌握 JUnit3.0
曾经公司做过一个.net的项目,在项目开发的过程中.我们採用的是分层的开发方式,大家先在一起讨论接口, 然后讨论完以后,形成文档,然后依照文档进行开发!这样就有一个问题,你必需要保证你的接口是正确的. ...
- codeforce447 D SGU 548 贪心+优先队列
codeforce447 D - DZY Loves Modification 题意:有一个n*m的矩阵,每次可以选择一行或者一列,可以得到这行或这列的所有元素sum的积分,然后使这一列/行的每一个元 ...
- Android 使用 Gmail 来发送邮件
Android 使用 Gmail 来发送邮件 1. [代码]SendMail.java package org.apache.android.mail; import android.app.Acti ...