前言
我在博客园潜水两三年了,在这里看过很多大神的文章,也学到了很多东西。可以说我是汲取着博客园的营养成长的。
想当年,我也是拿10个G的精神粮食从一个博客园大神那里换来一套开发框架,正式走上开发之路,到后来成为主力开发,再到项目经理再后来顺利拿下美工妹,也算是走上人生巅峰。
只索取,不分享就是自私,大家都这么自私还怎么做技术交流,说到分享首先想到的就是我那120G的精神粮食,但是分享这个好像有点法律风险,所以我把这几年在.net开发生涯中积累的一套框架分享给大家。
早上发过一篇博客,一会儿就让管理员拿掉了,这里我解释下完全没有广告推广的意思,我不会放置任何推广信息,没那个必要,房子、车子、妹子都有了,在一家还不错的单位上着班,不然也没这个闲心来做什么开源框架,目的是有,就是出来在新手面前装个逼。这样吧大家下了代码去看,里面如果有一点点广告嫌疑作者我小JJ自动缩短一厘米。
废话少说,先来介绍下这个开发框架。
框架名称:NFine.Framwork,牛逼框架,好框架
框架使用场景:OA、ERP、BPM、CRM、WMS、TMS、MIS等业务管理系统及后台系统
框架解决方案:
解决方案简介:
1、NFine.Code 底层核心类(开发时不涉及,可编绎成dll提供)。
2、NFine.Data 数据层(开发时不涉及,可编绎成dll提供)。
3、NFine.Application 应用(有点类似业务逻辑层)
4、NFine.Domain 领域层。
5、NFine.Mapping 数据库映射。
6、NFine.Repository 数据访问。
7、NFine.Web 前端视图及控制器。
框架主要运用技术:
-
1、前端技术
-
JS框架:jquery-2.1.1、Bootstrap.js、JQuery UI
-
CSS框架:Bootstrap v3.3.4(稳定是后台,UI方面根据需求自己升级改造吧)。
-
客户端验证:jQuery Validation Plugin 1.9.0。
-
在线编辑器:ckeditor、simditor
-
上传文件:Uploadify v3.2.1
-
动态页签:Jerichotab(自己改造)
-
数据表格:jqGrid、Bootstrap Talbe
-
对话框:layer-v2.3
-
下拉选择框:jQuery Select2
-
树结构控件:jQuery zTree、jQuery wdtree
-
页面布局:jquery.layout.js 1.4.4
-
图表插件:echarts、highcharts
-
日期控件: My97DatePicker
-
2、后端技术
-
核心框架:ASP.NET MVC5、WEB API
-
持久层框架:EntityFramework 6.0
-
定时计划任务:Quartz.Net组件
-
安全支持:过滤器、Sql注入、请求伪造
-
服务端验证:实体模型验证、自己封装Validator
-
缓存框架:微软自带Cache、Redis
-
日志管理:Log4net、登录日志、操作日志
-
工具类:NPOI、Newtonsoft.Json、验证码、丰富公共类似
框架代码风格:
数据库、仓库代码
1 using NFine.Code; 2 using System; 3 using System.Collections.Generic; 4 using System.Data.Common; 5 using System.Linq; 6 using System.Linq.Expressions; 7 8 namespace NFine.Data 9 { 10 ///11 /// 仓储接口 12 /// 13 /// 实体类型 14 public interface IRepositoryBase where TEntity : class,new() 15 { 16 int Insert(TEntity entity); 17 int Insert(List entitys); 18 int Update(TEntity entity); 19 int Delete(TEntity entity); 20 int Delete(Expression bool>> predicate); 21 TEntity FindEntity(object keyValue); 22 TEntity FindEntity(Expression bool>> predicate); 23 IQueryable IQueryable(); 24 IQueryable IQueryable(Expression bool>> predicate); 25 List FindList(string strSql); 26 List FindList(string strSql, DbParameter[] dbParameter); 27 List FindList(Pagination pagination); 28 List FindList(Expression bool>> predicate, Pagination pagination); 29 } 30 }
using NFine.Code; using System; using System.Collections.Generic; using System.Data.Common; using System.Data.Entity; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text.RegularExpressions;namespace NFine.Data {////// 仓储实现/// /// public class RepositoryBase : IRepositoryBase where TEntity : class,new(){public NFineDbContext dbcontext = new NFineDbContext();public int Insert(TEntity entity){dbcontext.Entry (entity).State = EntityState.Added;return dbcontext.SaveChanges();}public int Insert(List entitys){foreach (var entity in entitys){dbcontext.Entry (entity).State = EntityState.Added;}return dbcontext.SaveChanges();}public int Update(TEntity entity){dbcontext.Set ().Attach(entity);PropertyInfo[] props = entity.GetType().GetProperties();foreach (PropertyInfo prop in props){if (prop.GetValue(entity, null) != null){if (prop.GetValue(entity, null).ToString() == " ")dbcontext.Entry(entity).Property(prop.Name).CurrentValue = null;dbcontext.Entry(entity).Property(prop.Name).IsModified = true;}}return dbcontext.SaveChanges();}public int Delete(TEntity entity){dbcontext.Set ().Attach(entity);dbcontext.Entry (entity).State = EntityState.Deleted;return dbcontext.SaveChanges();}public int Delete(Expression bool>> predicate){var entitys = dbcontext.Set ().Where(predicate).ToList();entitys.ForEach(m => dbcontext.Entry (m).State = EntityState.Deleted);return dbcontext.SaveChanges();}public TEntity FindEntity(object keyValue){return dbcontext.Set ().Find(keyValue);}public TEntity FindEntity(Expression bool>> predicate){return dbcontext.Set ().FirstOrDefault(predicate);}public IQueryable IQueryable(){return dbcontext.Set ();}public IQueryable IQueryable(Expression bool>> predicate){return dbcontext.Set ().Where(predicate);}public List FindList(string strSql){return dbcontext.Database.SqlQuery (strSql).ToList ();}public List FindList(string strSql, DbParameter[] dbParameter){return dbcontext.Database.SqlQuery (strSql, dbParameter).ToList ();}public List FindList(Pagination pagination){bool isAsc = pagination.sord.ToLower() == "asc" ? true : false;string[] _order = pagination.sidx.Split(',');MethodCallExpression resultExp = null;var tempData = dbcontext.Set ().AsQueryable();foreach (string item in _order){string _orderPart = item;_orderPart = Regex.Replace(_orderPart, @"s+", " ");string[] _orderArry = _orderPart.Split(' ');string _orderField = _orderArry[0];bool sort = isAsc;if (_orderArry.Length == 2){isAsc = _orderArry[1].ToUpper() == "ASC" ? true : false;}var parameter = Expression.Parameter(typeof(TEntity), "t");var property = typeof(TEntity).GetProperty(_orderField);var propertyAccess = Expression.MakeMemberAccess(parameter, property);var orderByExp = Expression.Lambda(propertyAccess, parameter);resultExp = Expression.Call(typeof(Queryable), isAsc ? "OrderBy" : "OrderByDescending", new Type[] { typeof(TEntity), property.PropertyType }, tempData.Expression, Expression.Quote(orderByExp));}tempData = tempData.Provider.CreateQuery (resultExp);pagination.records = tempData.Count();tempData = tempData.Skip (pagination.rows * (pagination.page - 1)).Take (pagination.rows).AsQueryable();return tempData.ToList();}public List FindList(Expression bool>> predicate, Pagination pagination){bool isAsc = pagination.sord.ToLower() == "asc" ? true : false;string[] _order = pagination.sidx.Split(',');MethodCallExpression resultExp = null;var tempData = dbcontext.Set ().Where(predicate);foreach (string item in _order){string _orderPart = item;_orderPart = Regex.Replace(_orderPart, @"s+", " ");string[] _orderArry = _orderPart.Split(' ');string _orderField = _orderArry[0];bool sort = isAsc;if (_orderArry.Length == 2){isAsc = _orderArry[1].ToUpper() == "ASC" ? true : false;}var parameter = Expression.Parameter(typeof(TEntity), "t");var property = typeof(TEntity).GetProperty(_orderField);var propertyAccess = Expression.MakeMemberAccess(parameter, property);var orderByExp = Expression.Lambda(propertyAccess, parameter);resultExp = Expression.Call(typeof(Queryable), isAsc ? "OrderBy" : "OrderByDescending", new Type[] { typeof(TEntity), property.PropertyType }, tempData.Expression, Expression.Quote(orderByExp));}tempData = tempData.Provider.CreateQuery (resultExp);pagination.records = tempData.Count();tempData = tempData.Skip (pagination.rows * (pagination.page - 1)).Take (pagination.rows).AsQueryable();return tempData.ToList();}} }
自动映射对象实体
框架界面展示:
支持多皮肤切换
下一篇给大家讲解下如何实现动态皮肤切换
总结:
1:本文并没有详细讲解实现机制。
2:本文并没有详细讲解开发方式。
但,至少你可以:看源码、看API、看Demo,还可以加入技术交流群进行交流分享。
当然,后续我会补充相关文章,更加细化和完善的机制及开发方式。
如果您支持开源精神,在精神层面可以点赞以示鼓励
另外补充:有Bug及漏洞,请私下提交
框架开源地址:
1、源码下载地址:http://download.csdn.net/detail/nfine_2016/9608074