相隔上次的asp.net三层架构解析,不知道大家有木有去试试,做出一两个自己的功能模块,其实都很简单,只是在摸索的路上有些难而已。加油啊!未来不等人。
接着上次的教程继续说,还在学校的时候真的见识太少,对于现在公司的要求都是可望不可即,也就见怪不怪应届生的竞争力是多么不值得一提了,所以提前给自己找个好公司,去帮公司解决问题,才是学习和进步的正确方向,学校的生活只是一个儿时的梦想实现的倒影,不要过于迷恋了。
好了,又说教了,话说自己马上大四毕业,对于一些小学弟总是想多唠叨几句,嘿嘿为了你们好,要知道,社会不会袒护和关心任何人。学的东西都是自己的,下面来看看多层架构的企业网站级别是什么样子的。
这里由于版权之类的问题,我就不截图了,直接给大家看看做的代码截图,如图,
可以看到这才是社会需要的标准,我们还是太年轻了,因为这些东西还只是最基本的,不过给大家展示的这个企业后台客户关系管理系统的权限业务逻辑算是郑州的最高水准了,不信的可以慢慢看下面的演示,耐心。。
这个后台的复杂程度是和北京Lenovo研发部门持平的,PS:因为就是从那里传出来的,架构师说的。我用了大概九天才学会了这个系统的权限管理,因为里面可以控制权限到每个页面的标签,写的非常强大。
开始的接触的时候我是从PD入手的,看到了传说中的云图,公司规定这个不能带出,所以就没法给图了,不过这个图大概有30多个表,我也记不了啊。。不过为了给大家演示效果,我凭着印象大概记下了一些关键的业务逻辑构思的方法,试了画了一个,大家可以从图中清楚的分析出来这块的权限管理方法,如下图,PS:不知道这算不算给公司泄密。。我想应该不会有公司的人看的博客吧,我人气很低的。。看不到看不到。。毕竟公司这么框架,这个九牛一毛啊。好东西就是要分享学习嘛。
这样就熟悉了权限管理的业务逻辑实现方法,接下来就是对于使用什么样的架构来写这么庞大的一个系统,选择三层显然已经满足不了,所以就开始学习了传说中的多层架构 - 工厂模式来开发这个后台。一般的小公司会选择用动软来构架好一些基本的类库和方法,这样来一步步的修改功能,不过大公司的会考虑效率问题,最后我所在的公司介绍了一种代码生成器SocanCode,用这个的好处是可以定制属于自己的代码类库,非常巧妙的使用JS编写了一套替换代码的生成方法,大家可以试SocanCode,如图,PS:右侧的模版就是修改定制自己想要的代码规范,这里就不详述了,因为网上的教程很多,下面来介绍生成后的类库使用方法。
这样生成了我们要写的业务,三层架构的模版文件,如图,
然后把各种页面的四操作写出来,对于大家来说应该不难吧,我在上期写过一个例子,这里就不多说了。写好后就添加类库到本项目中,如图,
这样订制的代码有很高的质量,但是没什么成就感。给大家一个四操作的例子吧,省得有人说我不给demo,
TVisitBLL:
using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Web; using System.Web.Caching; namespace BLL { /// <summary> /// 业务逻辑类 TVisitBLL /// </summary> public class TVisitBLL: BLHelper { private readonly DAL.TVisitDAL dal = new DAL.TVisitDAL(); public TVisitBLL() : base("_TVisit_") { } /// <summary> /// 增加一条数据 /// </summary> public void Add(Model.TVisitModel model) { dal.Add(model); } /// <summary> /// 更新一条数据 /// </summary> public void Update(Model.TVisitModel model) { int count = dal.Update(model); if (EnableCache && count > 0) { RemoveModelCache(model.VisitId); } } /// <summary> /// 删除一条数据 /// </summary> public void Delete(int? VisitId) { int count = dal.Delete(VisitId); if (EnableCache && count > 0) { RemoveModelCache(VisitId.ToString()); } } /// <summary> /// 是否存在该记录 /// </summary> public bool Exists(int? VisitId) { bool bln = dal.Exists(VisitId); return bln; } /// <summary> /// 得到一个对象实体 /// </summary> public Model.TVisitModel GetModel(int? VisitId) { Model.TVisitModel model = null; if (!EnableCache) { model = dal.GetModel(VisitId); } else { string key = VisitId.ToString(); if (GetModelCache(key) != null) { model = (Model.TVisitModel)GetModelCache(key); } else { model = dal.GetModel(VisitId); TryAddModelCache(key, model, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null); } } return model; } /// <summary> /// 获得泛型数据列表 /// </summary> public List<Model.TVisitModel> GetList() { List<Model.TVisitModel> lst = dal.GetList(); return lst; } /// <summary> /// 分页获取泛型数据列表 /// </summary> public PageList<Model.TVisitModel> GetPageList(PageInfo pi) { PageList<Model.TVisitModel> pl = dal.GetPageList(pi); return pl; } } }
TVisitDAL:
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Text; namespace DAL { /// <summary> /// 数据访问类 TVisitDAL /// <summary> public partial class TVisitDAL : DALHelper { /// <summary> /// 增加一条数据 /// </summary> public int Add(Model.TVisitModel model) { IDbDataParameter[] parms4TVisit = PrepareAddParameters(model); return dbHelper.ExecuteNonQuery(CommandType.StoredProcedure, COMMAND_ADD, parms4TVisit); } /// <summary> /// 更新一条数据 /// </summary> public int Update(Model.TVisitModel model) { IDbDataParameter[] parms4TVisit = PrepareUpdateParameters(model); return dbHelper.ExecuteNonQuery(CommandType.StoredProcedure, COMMAND_UPDATE, parms4TVisit); } /// <summary> /// 删除一条数据 /// </summary> public int Delete(int? VisitId) { IDbDataParameter[] parms4TVisit = PrepareDeleteParameters(VisitId); return dbHelper.ExecuteNonQuery(CommandType.StoredProcedure, COMMAND_DELETE, parms4TVisit); } /// <summary> /// 得到一个对象实体 /// </summary> public Model.TVisitModel GetModel(int? VisitId) { IDbDataParameter[] parms4TVisit = PrepareGetModelParameters(VisitId); using (IDataReader dr = dbHelper.ExecuteReader(CommandType.StoredProcedure, COMMAND_GETMODEL, parms4TVisit)) { if (dr.Read()) return GetModel(dr); return null; } } /// <summary> /// 是否存在该记录 /// </summary> public bool Exists(int? VisitId) { IDbDataParameter[] parms4TVisit = PrepareExistParameters(VisitId); object obj = dbHelper.ExecuteScalar(CommandType.StoredProcedure, COMMAND_EXISTS, parms4TVisit); return int.Parse(obj.ToString()) > 0; } /// <summary> /// 获取数量 /// </summary> public int GetCount() { object obj = dbHelper.ExecuteScalar(CommandType.StoredProcedure, COMMAND_GETCOUNT, null); return int.Parse(obj.ToString()); } /// <summary> /// 获取泛型数据列表 /// </summary> public List<Model.TVisitModel> GetList() { using (IDataReader dr = dbHelper.ExecuteReader(CommandType.StoredProcedure, COMMAND_GETLIST, null)) { List<Model.TVisitModel> lst = new List<Model.TVisitModel>(); ExecuteReaderAction(dr, r => lst.Add(GetModel(r))); return lst; } } /// <summary> /// 分页获取泛型数据列表 /// </summary> public PageList<Model.TVisitModel> GetPageList(PageInfo pi) { pi.RecordCount = GetCount(); pi.Compute(); PageList<Model.TVisitModel> pl = new PageList<Model.TVisitModel>(pi); using (IDataReader dr = dbHelper.ExecuteReader(CommandType.Text, COMMAND_GETLIST, null)) { pl.List = new List<Model.TVisitModel>(); ExecuteReaderAction(dr, pi.FirstIndex, pi.PageSize, r => pl.List.Add(GetModel(r))); } return pl; } /// <summary> /// 由一行数据得到一个实体 /// </summary> private Model.TVisitModel GetModel(IDataReader dr) { Model.TVisitModel model = new Model.TVisitModel(); PrepareModel(model, dr); return model; } } }
TVisitDAL:
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Text; using DBUtility; namespace DAL { /// <summary> /// 数据访问类 TVisit ,此类请勿动,以方便表字段更改时重新生成覆盖 /// </summary> public partial class TVisitDAL { internal const string COMMAND_ADD = "sp_TVisit_Add"; internal const string COMMAND_UPDATE = "sp_TVisit_Update"; internal const string COMMAND_DELETE = "sp_TVisit_Delete"; internal const string COMMAND_EXISTS = "sp_TVisit_Exists"; internal const string COMMAND_GETMODEL = "sp_TVisit_GetModel"; internal const string COMMAND_GETCOUNT = "sp_TVisit_GetCount"; internal const string COMMAND_GETLIST = "sp_TVisit_GetAllList"; internal const string PARM_VISITID = "@in_VisitId"; internal const string PARM_VISITTIME = "@in_VisitTime"; internal const string PARM_VISITCUSTOMER = "@in_VisitCustomer"; internal const string PARM_VISITWAY = "@in_VisitWay"; internal const string PARM_VISITCONTENT = "@in_VisitContent"; internal const string PARM_VISITOR = "@in_Visitor"; internal const string PARM_FREMARK = "@in_FRemark"; internal const string PARM_FSORT = "@in_FSort"; internal const string PARM_FISDELETE = "@in_FIsDelete"; internal const string PARM_FCREATOR = "@in_FCreator"; internal const string PARM_FCREATEDATE = "@in_FCreateDate"; internal const string PARM_FMODIFY = "@in_FModify"; internal const string PARM_FMODIFYDATE = "@in_FModifyDate"; internal const string PARM_FGUID = "@in_FGUID"; internal const string PARM_FISSYNCHRONOUS = "@in_FIsSynchronous"; /// <summary> /// 为新增一条数据准备参数 /// </summary> internal static IDbDataParameter[] PrepareAddParameters(Model.TVisitModel model) { IDbDataParameter[] parms = DbParameterCache.GetCachedParameterSet(dbHelper.ConnectionString, COMMAND_ADD); if (parms == null) { parms = new IDbDataParameter[]{ dbHelper.CreateDbParameter(PARM_VISITTIME, DbType.DateTime, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_VISITCUSTOMER, DbType.Int32, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_VISITWAY, DbType.Int32, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_VISITCONTENT, DbType.AnsiString, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_VISITOR, DbType.Int32, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FREMARK, DbType.String, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FSORT, DbType.Int32, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FISDELETE, DbType.Boolean, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FCREATOR, DbType.AnsiString, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FCREATEDATE, DbType.DateTime, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FMODIFY, DbType.AnsiString, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FMODIFYDATE, DbType.DateTime, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FGUID, DbType.AnsiString, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FISSYNCHRONOUS, DbType.Boolean, ParameterDirection.Input)}; DbParameterCache.CacheParameterSet(dbHelper.ConnectionString, COMMAND_ADD, parms); } parms[0].Value = model.VisitTime; parms[1].Value = model.VisitCustomer; parms[2].Value = model.VisitWay; parms[3].Value = model.VisitContent; parms[4].Value = model.Visitor; parms[5].Value = model.FRemark; parms[6].Value = model.FSort; parms[7].Value = model.FIsDelete; parms[8].Value = model.FCreator; parms[9].Value = model.FCreateDate; parms[10].Value = model.FModify; parms[11].Value = model.FModifyDate; parms[12].Value = model.FGUID; parms[13].Value = model.FIsSynchronous; return parms; } /// <summary> /// 为更新一条数据准备参数 /// </summary> internal static IDbDataParameter[] PrepareUpdateParameters(Model.TVisitModel model) { IDbDataParameter[] parms = DbParameterCache.GetCachedParameterSet(dbHelper.ConnectionString, COMMAND_UPDATE); if (parms == null) { parms = new IDbDataParameter[]{ dbHelper.CreateDbParameter(PARM_VISITTIME, DbType.DateTime, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_VISITCUSTOMER, DbType.Int32, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_VISITWAY, DbType.Int32, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_VISITCONTENT, DbType.AnsiString, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_VISITOR, DbType.Int32, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FREMARK, DbType.String, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FSORT, DbType.Int32, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FISDELETE, DbType.Boolean, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FCREATOR, DbType.AnsiString, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FCREATEDATE, DbType.DateTime, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FMODIFY, DbType.AnsiString, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FMODIFYDATE, DbType.DateTime, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FGUID, DbType.AnsiString, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_FISSYNCHRONOUS, DbType.Boolean, ParameterDirection.Input), dbHelper.CreateDbParameter(PARM_VISITID, DbType.Int32, ParameterDirection.Input)}; DbParameterCache.CacheParameterSet(dbHelper.ConnectionString, COMMAND_UPDATE, parms); } parms[0].Value = model.VisitTime; parms[1].Value = model.VisitCustomer; parms[2].Value = model.VisitWay; parms[3].Value = model.VisitContent; parms[4].Value = model.Visitor; parms[5].Value = model.FRemark; parms[6].Value = model.FSort; parms[7].Value = model.FIsDelete; parms[8].Value = model.FCreator; parms[9].Value = model.FCreateDate; parms[10].Value = model.FModify; parms[11].Value = model.FModifyDate; parms[12].Value = model.FGUID; parms[13].Value = model.FIsSynchronous; parms[14].Value = model.VisitId; return parms; } /// <summary> /// 为删除一条数据准备参数 /// </summary> internal static IDbDataParameter[] PrepareDeleteParameters(int? VisitId) { IDbDataParameter[] parms = DbParameterCache.GetCachedParameterSet(dbHelper.ConnectionString, COMMAND_DELETE); if (parms == null) { parms = new IDbDataParameter[]{ dbHelper.CreateDbParameter(PARM_VISITID, DbType.Int32, ParameterDirection.Input)}; DbParameterCache.CacheParameterSet(dbHelper.ConnectionString, COMMAND_EXISTS, parms); } parms[0].Value = VisitId; return parms; } /// <summary> /// 为查询是否存在一条数据准备参数 /// </summary> internal static IDbDataParameter[] PrepareExistParameters(int? VisitId) { IDbDataParameter[] parms = DbParameterCache.GetCachedParameterSet(dbHelper.ConnectionString, COMMAND_EXISTS); if (parms == null) { parms = new IDbDataParameter[]{ dbHelper.CreateDbParameter(PARM_VISITID, DbType.Int32, ParameterDirection.Input)}; DbParameterCache.CacheParameterSet(dbHelper.ConnectionString, COMMAND_EXISTS, parms); } parms[0].Value = VisitId; return parms; } /// <summary> /// 为获取一条数据准备参数 /// </summary> internal static IDbDataParameter[] PrepareGetModelParameters(int? VisitId) { IDbDataParameter[] parms = DbParameterCache.GetCachedParameterSet(dbHelper.ConnectionString, COMMAND_GETMODEL); if (parms == null) { parms = new IDbDataParameter[]{ dbHelper.CreateDbParameter(PARM_VISITID, DbType.Int32, ParameterDirection.Input)}; DbParameterCache.CacheParameterSet(dbHelper.ConnectionString, COMMAND_EXISTS, parms); } parms[0].Value = VisitId; return parms; } /// <summary> /// 由一行数据得到一个实体 /// </summary> internal static void PrepareModel(Model.TVisitModel model, IDataReader dr) { model.VisitId = DbValue.GetInt(dr["VisitId"]); model.VisitTime = DbValue.GetDateTime(dr["VisitTime"]); model.VisitCustomer = DbValue.GetInt(dr["VisitCustomer"]); model.VisitWay = DbValue.GetInt(dr["VisitWay"]); model.VisitContent = DbValue.GetString(dr["VisitContent"]); model.Visitor = DbValue.GetInt(dr["Visitor"]); model.FRemark = DbValue.GetString(dr["FRemark"]); model.FSort = DbValue.GetInt(dr["FSort"]); model.FIsDelete = DbValue.GetBool(dr["FIsDelete"]); model.FCreator = DbValue.GetString(dr["FCreator"]); model.FCreateDate = DbValue.GetDateTime(dr["FCreateDate"]); model.FModify = DbValue.GetString(dr["FModify"]); model.FModifyDate = DbValue.GetDateTime(dr["FModifyDate"]); model.FGUID = DbValue.GetString(dr["FGUID"]); model.FIsSynchronous = DbValue.GetBool(dr["FIsSynchronous"]); } } }
TVisitModel:
using System; using System.Collections.Generic; namespace Model { /// <summary> /// 实体类 TVisitModel /// </summary> public partial class TVisitModel { } }
TVisitModel:
using System; namespace Model { /// <summary> /// 实体类 TVisitModel, 此类请勿动,以方便表字段更改时重新生成覆盖 /// </summary> [Serializable] public partial class TVisitModel : ICloneable { public TVisitModel() { } /// <summary> /// 构造函数 TVisitModel /// </summary> /// <param name="visitid">拜访编号</param> /// <param name="visittime">拜访时间</param> /// <param name="visitcustomer">拜访对象编号</param> /// <param name="visitway">拜访方式</param> /// <param name="visitcontent">拜访内容</param> /// <param name="visitor">拜访人员</param> /// <param name="fremark">备注</param> /// <param name="fsort">显示顺序</param> /// <param name="fisdelete">是否被删除:默认0</param> /// <param name="fcreator">创建者</param> /// <param name="fcreatedate">创建日期</param> /// <param name="fmodify">修改者</param> /// <param name="fmodifydate">修改日期</param> /// <param name="fguid">唯一标识</param> /// <param name="fissynchronous">是否已同步</param> public TVisitModel(int? visitid, DateTime? visittime, int? visitcustomer, int? visitway, string visitcontent, int? visitor, string fremark, int? fsort, bool? fisdelete, string fcreator, DateTime? fcreatedate, string fmodify, DateTime? fmodifydate, string fguid, bool? fissynchronous) { this.VisitId = visitid; this.VisitTime = visittime; this.VisitCustomer = visitcustomer; this.VisitWay = visitway; this.VisitContent = visitcontent; this.Visitor = visitor; this.FRemark = fremark; this.FSort = fsort; this.FIsDelete = fisdelete; this.FCreator = fcreator; this.FCreateDate = fcreatedate; this.FModify = fmodify; this.FModifyDate = fmodifydate; this.FGUID = fguid; this.FIsSynchronous = fissynchronous; } #region 实体属性 /// <summary> /// 拜访编号 /// </summary> public int? VisitId { get; set; } /// <summary> /// 拜访时间 /// </summary> public DateTime? VisitTime { get; set; } /// <summary> /// 拜访对象编号 /// </summary> public int? VisitCustomer { get; set; } /// <summary> /// 拜访方式 /// </summary> public int? VisitWay { get; set; } /// <summary> /// 拜访内容 /// </summary> public string VisitContent { get; set; } /// <summary> /// 拜访人员 /// </summary> public int? Visitor { get; set; } /// <summary> /// 备注 /// </summary> public string FRemark { get; set; } /// <summary> /// 显示顺序 /// </summary> public int? FSort { get; set; } /// <summary> /// 是否被删除:默认0 /// </summary> public bool? FIsDelete { get; set; } /// <summary> /// 创建者 /// </summary> public string FCreator { get; set; } /// <summary> /// 创建日期 /// </summary> public DateTime? FCreateDate { get; set; } /// <summary> /// 修改者 /// </summary> public string FModify { get; set; } /// <summary> /// 修改日期 /// </summary> public DateTime? FModifyDate { get; set; } /// <summary> /// 唯一标识 /// </summary> public string FGUID { get; set; } /// <summary> /// 是否已同步 /// </summary> public bool? FIsSynchronous { get; set; } #endregion #region ICloneable 成员 public object Clone() { return this.MemberwiseClone(); } #endregion public override bool Equals(object obj) { Model.TVisitModel model = obj as Model.TVisitModel; if (model != null && model.VisitId == this.VisitId) return true; return false; } public override int GetHashCode() { return VisitId.GetHashCode(); } } }
总算写完了这个业务的功能模块代码,呃。。。累死了,继续说,下面就可以基于其他的模块进行系统的四操作开发了,比如,在web里面写自己的页面,提示:这里大家可以定义一个topmasterSite1.Master放置自己的title功能显示,这样就避免了很多繁杂的多余模块的产生,PS:这个是架构师教我的,嘿嘿。。。
好了到这里就给大家简单的介绍完了多层架构的基本使用方法了,工厂的核心在于接口的调用,其实也就多了接口的实例化引用对象,可以方便的调用到各种XXOODAL,所以大家如果想用好多层就要学会接口的方法使用。大部分的网站都可以用三层解决的话,是不建议用工厂的,所以掌握住基本的才是王道。
这次的东西有点多,大家慢慢理解,我会再用一期的时间把这个项目简单的介绍完,让大家知道其中的一些核心写法,具体的细节需要大家自己去写代码去修改和优化。
最后感谢 @莉子姐 , @米米姐 , @蘑菇姐 ,辛苦了各位,我们下期继续,大家一起加油!Goodnight!