Laiwen asp.net 架构
这段时间看了些开源代码,感觉收益非浅。结合我的工作经验,写了套asp.net 架构,暂时命名为Laiwen。从今天开始我将和网友们共同分享我的创作乐趣。
我把网站分成 6 个组成项目。(图1)
分别是:
Web 项目(LaiwenAdmin,LaiwenMain 可以是多个Web项目)
数据访问和业务层项目(DALBusiness)
实体层项目(DataEntity,工具生成)
存储过程层项目 (ProcLogic,工具生成)
数据库配置项目 (DataBase)
工具项目 (Common,基础同用类库,可用于任何asp.net 项目)。
当然,实际应用中还会有其它不同类型的项目,如WebService等,但我认为应把它们在DALBusiness 中包装,不要直接在Web项目中引用。
下面,我们分别介绍一下这几个项目。
1.Web 项目(图2)

Web 项目应该尽量用目录结构区分功能。比如,我在AppControl文件夹中写只在此web站点应用的自定义控件,在Javascript文件夹中存放此web项目公用的js文件(所有项目通用的js 用资源文件的形式放在Common中),Project 文件夹中按功能目录结构存放其他文件。
Web 项目会直接用到Common, DALBusiness, ProcLogic 几个项目。
应用我这套架构必须配好Web.Config。具体配置方法我将在解说具体功能的时候介绍。
2.数据访问和业务层项目(DALBusiness)
DAL 和 Business 文件夹
我把数据访问层DAL 和 业务层Business 都放在了 DALBusiness 项目中,分别对应DAL和Business文件夹。在DAL下的类全部用internal关键字修饰,这样使其对其它项目不可见。当Web项目进行业务操作时只能调用Business, 这就保证了业务操作的严谨性,统一性,业务的密闭性,为今后的可维护性提供可有效的保证。
下面是DAL层调用的几个例子:
public static DataTable SearchAdPosition(string description, string adPositionKey, int currentPage, int pagesize, out int count)
{
using (IDbConnection cn = SqlTools.Help.dataProvider.GetConnection())
{
IDbCommand cmd = SqlCmd.Factory.Ad.SearchAdPosition(cn, description, adPositionKey, currentPage, pagesize, out count);
return SqlTools.Help.ExecuteDataTable(cmd);
}
}
public static DataTable AdPosition_ByAll(CmdLogic.AdPosition_ByAll logic)
{
return SqlTools.Help.ExecuteDataTable(logic.GetProcName(), logic.GetObjects());
}
public static DataTable SearchUser(int currentPage, int pagesize, out int count)
{
System.Data.IDbConnection iconn = Laiwen.DataBase.SqlTools.Help.dataProvider.GetConnection();
Common.DataAccess.ORMapping.IConvert ic = Laiwen.DataBase.SqlTools.Help.dataProvider.GetIConvert();
Common.DataAccess.ORMapping.Mapping map = ic.GetNewMapping();
Common.Utilities.ListDic<string, object> sqlParams = new Common.Utilities.ListDic<string, object>();
sqlParams.Add("Tel", "uuuu");
Common.DataAccess.SplitHelp.AscDescClass ascdesc = new Common.DataAccess.SplitHelp.AscDescClass();
ascdesc.Add("UserName", Common.DataAccess.SplitHelp.AscDescEnum.desc);
int count;
DataTable dt = map.Select("SS_User", "UserName,Tel", "Tel <> @Tel", sqlParams, ascdesc, currentPage, pagesize, out count, iconn);
iconn.Close();
return dt;
}
AppControl 文件夹
此文件夹中写在此解决方案所有web站点都会用到的web自定义控件。
ConfigMain 和 ConfigMain 文件夹
分别对应LaiwenMain 和 LaiwnAdmin 两个Web项目 ,它们的AppSetting.cs 和 UrlInfo.cs 分别对应各自的Web.confg中的AppSetting 和 Url。
例如:

/**//// <summary>
/// 分页大小
/// </summary>
public static int PageSize
{
get
{
return int.Parse(System.Configuration.ConfigurationManager.AppSettings["PageSize"]);
}
}
命名规则#region 命名规则
// 此类的作用是对访问Web项目中的地址及路径提供帮助
//
// ***************** 命名规则 *******************
//
// A
地址:
// 我们把一个地址分成四部分:
// 1. Url主体部分,如:http://www.edulink.com.cn/default.aspx
// 命名规则:“Url_功能描述”
// 也可加上查询的部分,单视为一体 如:http://www.edulink.com.cn/default.aspx?Ky=Value
//
// 2. 查询键
// 命名规则:Key_名称
//
// 3. 查询值
// 命名规则:Value_值
//
// 4. 查询键值组合
// 命名规则:KeyValue_名称
//
// B
路径:
// 命名规则:Path_名称
#endregion
public class UrlInfo
{

网站 UrlBase#region 网站 UrlBase
/**//// <summary>
/// 网站 UrlBase
/// </summary>
public static string UrlBase
{
get
{
return AppSetting.LaiwenAdmin;
}
}
#endregion
}
EnumType 文件夹
提供枚举和枚举字典 例如:

命名规则#region 命名规则
// 此类的作用是对访问Web项目中的地址及路径提供帮助
//
// ***************** 命名规则 *******************
//
// A
地址:
// 我们把一个地址分成四部分:
// 1. Url主体部分,如:http://www.edulink.com.cn/default.aspx
// 命名规则:“Url_功能描述”
// 也可加上查询的部分,单视为一体 如:http://www.edulink.com.cn/default.aspx?Ky=Value
//
// 2. 查询键
// 命名规则:Key_名称
//
// 3. 查询值
// 命名规则:Value_值
//
// 4. 查询键值组合
// 命名规则:KeyValue_名称
//
// B
路径:
// 命名规则:Path_名称
#endregion
public class UrlInfo
{

网站 UrlBase#region 网站 UrlBase
/**//// <summary>
/// 网站 UrlBase
/// </summary>
public static string UrlBase
{
get
{
return AppSetting.LaiwenAdmin;
}
}
#endregion
} SqlCmd 文件夹
其中的类都要加上 internal 属性,只能在此项目中访问(在DAL中应用)。作用是提供SQL查询的Cmd,主要用在有很多可选择条件的查询。 在此文件夹下,又分为Factory, Sql 两个文件夹。在DAL调用SqlCmd中的代码时,应该调用Factory中的代码,Sql中的代码只应在Factory中的代码中调用。示例如下:
public static IDbCommand Search(IDbConnection cn, string courseName, int isApproved, string broadcastDatetime, int currentPage, int pagesize, out int count)
{
/**//* 如果有多类型 */
//if(cn.GetType().ToString() == "System.Data.SqlClient.SqlConnection")
//{
// 根据类型调用不同的方法
//}
IDbCommand cmd = new Sql.ES_BroadCastCourse(cn).Search(courseName, isApproved, broadcastDatetime, currentPage, pagesize, out count);
return cmd;
}
public IDbCommand Search_CourseBroadcastVE(string courseName, int isApproved, DateTime? broadcastDatetime1, DateTime? broadcastDatetime2, int currentPage, int pagesize, out int count)
{
SqlParameter param;
SqlCommand cmd = cn.CreateCommand();
cmd.CommandType = CommandType.Text;
StringBuilder sbWhere = new StringBuilder(" where 1=1 ");

构造参数#region 构造参数
if (courseName != "")
{
param = new SqlParameter();
param.ParameterName = "@courseName";
param.SqlDbType = SqlDbType.NVarChar;
param.Size = 200;
param.Direction = ParameterDirection.Input;
param.Value = courseName;
cmd.Parameters.Add(param);
sbWhere.Append(" and courseName like '%' + @courseName + '%'");
}
if (isApproved > ConstClass.nullFlag)
{
param = new SqlParameter();
param.ParameterName = "@isApproved";
param.SqlDbType = SqlDbType.Bit;
param.Size = 1;
param.Direction = ParameterDirection.Input;
param.Value = isApproved;
cmd.Parameters.Add(param);
sbWhere.Append(" and isApproved = @isApproved");
}
if (broadcastDatetime1 != null)
{
param = new SqlParameter();
param.ParameterName = "@broadcastDatetime1";
param.SqlDbType = SqlDbType.DateTime;
param.Size = 16;
param.Direction = ParameterDirection.Input;
param.Value = System.Convert.ToDateTime(broadcastDatetime1);
cmd.Parameters.Add(param);
sbWhere.Append(" and DateBegin >= @broadcastDatetime1 ");
}
if (broadcastDatetime2 != null)
{
param = new SqlParameter();
param.ParameterName = "@broadcastDatetime2";
param.SqlDbType = SqlDbType.DateTime;
param.Size = 16;
param.Direction = ParameterDirection.Input;
param.Value = System.Convert.ToDateTime(broadcastDatetime2);
cmd.Parameters.Add(param);
sbWhere.Append(" and DateBegin < @broadcastDatetime2 ");
}

#endregion
cmd.CommandText = "select count(*) from [ES_CourseBroadcast_VE]" + sbWhere.ToString();
if (cn.State != ConnectionState.Open)
cn.Open();
count = (int)cmd.ExecuteScalar();
//搜索的前n条
int topAll = SplitPage.GetTopNum(currentPage, pagesize, count);
AscDescClass ascDesc = new AscDescClass("DateBegin", AscDescEnum.desc);
//此sql语名必须有排序
string sql = String.Format(@"select top {0} * from [ES_CourseBroadcast_VE] {1} order by {2}", topAll, sbWhere.ToString(), ascDesc.GetAscDesString());
//最终sql
cmd.CommandText = SplitPage.GetFinalSql(sql, ascDesc, pagesize, count, topAll, currentPage);
return cmd;
}
Tools 文件夹
提供此解决方案的其它帮助类。
今天先说道这。
posted on 2006-10-13 14:13 来问(zljGood@hotmail.com) 阅读(257) 评论(1) 编辑 收藏
