SlickOne敏捷开发框架介绍(一) -- 基于Dapper, Mvc和WebAPI 的快速开发框架
前言:在两年前(最初发布时间:2013年1月9日(csdn),当前文章时间2015年11月10日),项目组推出了基于Dapper,Mvc和WebApi的快速开发框架,随着后续Slickflow产品的实践和应用,今再次对SlickOne项目做以回顾和总结。其目的是精简,持续改进,保持重构,让开发人员了解到最新的变化,尤其是全栈开发人员做以参考。
两年之前的博客文章可以查阅(最初发布时间:2013年1月9日):
http://blog.csdn.net/besley/article/details/8479943
1. 新版本变化综述:
1) Dapper部分的变化:
Dapper本身有支持对数据库底层接口,此次主要是增加了Oracle和MySQL数据库的接口,也修改了Dapper里面的SqlMapper文件。
2) SlickOne.Data 数据访问
在泛型封装的基础上,提供了列表分页,新增主键ID返回,根据多ID值查询返回列表,新增查询功能的存储过程等接口。
3) Mvc/WebApi
将两个类型的项目动态库文件整合在一个Web项目里面,同时响应页面请求和Api请求。
4) Web前端
由JQueryUI 转换到 Bootstrap框架,核心组件SlickGrid 转换为Bootstrap样式。
2. 框架设计
1) 数据访问Repository泛型类
Repository泛型类,彻底实现数据快速访问,不用重复编写不同实体的通用基本方法;而且此泛型类的存在也用以支持Dapper,EF,Heibernate等各种数据访问框架,考虑到不同用户的技术储备,只要去实现IRepository的接口方法就可以继续使用自己喜欢的框架。

2) 基于简单实体访问
简单实体,原始来源为数据库表的对应实体,而且并限定为只包含属性字段。在早期版本区分了数据实体和业务实体,有AutoMapper的转换工具,在新版本里面,不再强调业务实体,而是统一命名为简单实体,始终根据简单实体做业务功能开发,做数据的存储和读取。
3) 接口定义优先策略
接口方法更加侧重于业务过程的定义。基本方法如新增,编辑和删除可以直接快速调用Repository里的泛型方法,不再默认自动生成Partial文件去维护,包括Interface, Service类和ApiController类都不再生成Partial类文件。
4) WebApi 接口封装
消息体引用ResponseResult泛型类,包括状态(Status),消息(Message)和实体(Entity)关键属性。ResponseResult类用于服务端到前端的数据和消息封装,消息内容格式是JSON数据格式。
5) Javascript模板引擎
采用前端Javascript模板引擎,解析WebApi传递回的JSON对象,做前端界面展现。模板引擎可以采用HandlebarsJS或DustJS。也可以选择其它模板引擎。
6) Bootstrap
前端框架过渡到Bootstrap框架,相应的控件,如SlickGrid和ZTree等控件都可以找到对应Bootstrap的样式版本。
3. 解决方案结构图示

4. 项目代码实例
1) 实体对象
/// <summary>
/// 产品实体对象
/// </summary>
[Table("PrdProduct")]
public class ProductEntity
{
public int ID { get; set; }
public string ProductName { get; set; }
public string ProductCode { get; set; }
public string ProductType { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public string Notes { get; set; }
}
2) 接口定义
/// <summary>
/// 产品服务接口
/// </summary>
public interface IProductService
{
List<ProductEntity> GetProductList();
}
3) 服务实现
/// <summary>
/// 获取列表数据(示例查询方法,实际会用到分页,此处用于演示。)
/// </summary>
/// <returns></returns>
public List<ProductEntity> GetProductList()
{
var sql = @"SELECT ID,
ProductName,
ProductCode,
ProductType,
UnitPrice,
CreatedDate
FROM PrdProduct";
var list = QuickReporsitory.Query<ProductEntity>(sql, null)
.ToList();
return list;
}
4) WebApi
/// <summary>
/// 获取产品列表
/// </summary>
/// <returns></returns>
[HttpGet]
public ResponseResult<List<ProductEntity>> GetProductList()
{
var result = ResponseResult<List<ProductEntity>>.Default();
try
{
var list = ProductService.GetProductList();
result = ResponseResult<List<ProductEntity>>.Success(list);
}
catch (System.Exception ex)
{
result = ResponseResult<List<ProductEntity>>.Error(
string.Format("读取{0}数据失败, 错误:{1}", "产品列表", ex.Message)
);
}
return result;
}
5) 前端脚本
productlist.load = function () {
jshelper.ajaxGet("/soneweb/api/product/GetProductList", null, function (result) {
if (result.Status == 1) {
var columnProduct = [
{ id: "ID", name: "ID", field: "ID", width: 40, cssClass: "bg-gray" },
{ id: "ProductName", name: "名称", field: "ProductName", width: 120, cssClass: "bg-gray" },
{ id: "ProductCode", name: "编码", field: "ProductCode", width: 120, cssClass: "bg-gray" },
{ id: "ProductType", name: "类型", field: "ProductType", width: 160, cssClass: "bg-gray" },
{ id: "UnitPrice", name: "单价", field: "UnitPrice", width: 160, cssClass: "bg-gray" },
{ id: "CreatedDate", name: "创建时间", field: "CreatedDate", width: 200, cssClass: "bg-gray", formatter: datetimeFormatter },
];
var optionsProduct = {
editable: true,
enableCellNavigation: true,
enableColumnReorder: true,
asyncEditorLoading: true,
forceFitColumns: false,
topPanelHeight: 25
};
var dsProduct = result.Entity;
var dvProduct = new Slick.Data.DataView({ inlineFilters: true });
var gridProduct = new Slick.Grid("#myProductGrid", dvProduct, columnProduct, optionsProduct);
dvProduct.onRowsChanged.subscribe(function (e, args) {
gridProduct.invalidateRows(args.rows);
gridProduct.render();
});
dvProduct.onRowCountChanged.subscribe(function (e, args) {
gridProduct.updateRowCount();
gridProduct.render();
});
dvProduct.beginUpdate();
dvProduct.setItems(dsProduct, "ID");
gridProduct.setSelectionModel(new Slick.RowSelectionModel());
dvProduct.endUpdate();
gridProduct.onSelectedRowsChanged.subscribe(function (e, args) {
var selectionRowIndex = args.rows[0];
var row = dvProduct.getItemByIdx(selectionRowIndex);
if (row) {
productlist.mselectedProductID = row.ID;
productlist.mselectedProductRow = row;
}
});
};
});
function datetimeFormatter(row, cell, value, columnDef, dataContext) {
if (value != null && value != "") {
return value.substring(0, 10);
}
}
}
6) 页面呈现

5. 项目应用场景
SlickOne适用于BS/CS等架构的系统,目前已经用于Web网站项目,电商ERP,OA,工作流和App等各种类型的系统。
6. 项目资源
SlickOne项目开源地址:
http://github.com/besley/slickone
(包含数据库脚本文件)
SlickOne 做框架基础的权限管理:
http://github.com/besley/slicksafe
SlickSafe 权限管理在线DEMO:
http://demo.slickflow.com/ssweb/
7. 特别致谢
感谢随风,青文等网友对项目代码的贡献,开源能让大家集体参与,能让更多人分享代码成果。
8. 培训及技术支持
为团队开发人员快速上手,Slickflow项目组提供线上开发框架架构设计培训,流程引擎培训,SlickGrid插件开发培训等服务,欢迎留言或咨询。
9. 在线QQ交流群
QQ群: 151650479
SlickOne敏捷开发框架介绍(一) -- 基于Dapper, Mvc和WebAPI 的快速开发框架的更多相关文章
- SlickOne -- 基于Dapper, Mvc和WebAPI 的快速开发框架
前言:在两年前,项目组推出了基于Dapper,Mvc和WebApi的快速开发框架,随着后续Slickflow产品的实践和应用,今再次对SlickOne项目做以回顾和总结.其目的是精简,持续改进,保持重 ...
- 我和小美的撸码日记--基于MVC+Jqgrid的.Net快速开发框架
前言:以前的帐号没有发首页的权限,特此把这篇文章从另外一个博客移过来,这篇是<我和小美的撸码日记>的序 一转眼务农6年了,呆过大公司也去过小作坊,码农的人生除了抠腚还是抠腚.在所有呆过的公 ...
- c# 基于WebApi的快速开发框架FastFramework
一.框架简介 此框架是针对于webapi进行开发,项目分层是基于ABP框架的分层,更好的抽离业务逻辑关系,ABP是基于EF做数据访问层,本人个人比较喜欢Dapper,就把数据访问层封装成了Dapper ...
- Rookey.Frame企业级快速开发框架开源了
Rookey.Frame是一套基于.NET MVC + easyui的企业级极速开发框架,支持简单逻辑模块零代码编程.支持工作流(BPM).支持二次开发,具有高扩展性.高复用性.高伸缩性:应广大网友要 ...
- SlickOne 敏捷开发框架介绍(二) -- 多用户/多租户/SAAS软件基础框架实现
前言:在应用于集团版客户或SAAS平台服务的业务系统中,流程管理系统需要支持多用户组织模型.其中包括角色数据.流程定义数据和流程实例数据的多用户标识绑定.本文旨在全面描述如何基于SlickOne敏捷开 ...
- 基于ASP.NET MVC的热插拔模块式开发框架(OrchardNoCMS)介绍(二)
基于ASP.NET MVC的热插拔模块式开发框架(OrchardNoCMS)介绍(二) 之前文章中给大家说明了下我这个小小的想法,发现还是有不少人的支持和关注.你们的鼓励是对我最大的支持. 我总结了了 ...
- 快速开发框架,及库存管理系统,基于easyui框架和C#语言MVC、EntityFrameWork、T4模板技术。
快速开发框架,及库存管理系统,基于easyui框架和C#语言MVC.EntityFrameWork.T4模板技术. 产品界面如下图所示: 源码结构: 开放全部源码,如有需要请联系,QQ:1107141 ...
- Spring4.X + spring MVC + Mybatis3 零配置应用开发框架搭建详解(1) - 基本介绍
Spring4.X + spring MVC + Mybatis3 零配置应用开发框架搭建详解(1) - 基本介绍 spring集成 mybatis Spring4.x零配置框架搭建 两年前一直在做后 ...
- 基于Dapper的开源Lambda扩展,且支持分库分表自动生成实体之基础介绍
LnskyDB LnskyDB是基于Dapper的Lambda扩展,支持按时间分库分表,也可以自定义分库分表方法.而且可以T4生成实体类免去手写实体类的烦恼. 文档地址: https://lining ...
随机推荐
- 【Educational Codeforces Round28】
咸鱼选手发现自己很久不做cf了,晚节不保. A.Curriculum Vitae 枚举一下间断点的位置. #include<bits/stdc++.h> using namespace s ...
- Python之 context manager
在context manager中,必须要介绍两个概念: with as... , 和 enter , exit. 下文将先介绍with语句,然后介绍 __enter__和exit, 最后介绍cont ...
- Python基础:内置函数
本文基于Python 3.6.5的标准库文档编写,罗列了英文文档中介绍的所有内建函数,并对其用法进行了简要介绍. 下图来自Python官网:展示了所有的内置函数,共计68个(14*4+12),大家可以 ...
- Session和Cookie,Django的自动登录机制
什么是Cookie? Cookie是浏览器的本地存储机制,存储服务器返回的各种信息,下次发起请求时再发送给服务端,比如访问baidu 什么是Session? 刚才说道,Cookie存储服务端返回的信息 ...
- NOIP2002普及T3【产生数】
做完发现居然没人用map搞映射特意来补充一发 很容易看出这是一道搜索题考虑搜索方案,如果按字符串转移,必须存储每种状态,空间复杂度明显会爆炸观察到每一位之间是互不影响的 考虑使用乘法原理搜索出每一位的 ...
- 20165301 2017-2018-2《Java程序设计》课程总结
20165301 2017-2018-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:我期待的师生关系 预备作业2:学习基础与c语言学习心得 预备作业3: Linux安装及命 ...
- Python学习笔记:import sys模块(argv、path、platform、exit)
sys模块是Python标准库中自带的一个模块. sys模块包括了一组非常实用的服务,内含很多函数方法和变量,用来处理Python运行时配置以及资源,从而可以与当前程序之外的系统环境交互,如:Pyth ...
- JS实现点击图片,在浏览器中查看。
工作中遇到要实现点击图片查看的功能,从网上找了一段js代码,可以用. <img src="/pic/${pictureCertificate}" alt="凭证&q ...
- 【LOJ】#2041. 「SHOI2015」聚变反应炉
题解 这显然是一道题拆成两道 然后我胡乱分析了一波,决定第一题就用点度贪心(反正散播的能量肯定能被使用),然后过了 第二题开始mengbier 设\(f_u\)表示第u个点在父亲发动之后才发动的最小价 ...
- 在centOS使用systemctl配置启动多个tomcat
公司服务器使用的是阿里云CentOS7,CentOS7和CentOS6目前最大区别就是service变成了现在的systemctl,简单的查了一下并结合使用,发现systemctl功能上等同于6上面的 ...