EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(六)
前言
- 在接下来的篇幅里将对系统的模块功能进行编写。主要以代码实现为主。这一篇我们需要完成系统模块“角色管理”的相关功能。完成后可以对系统框架结构有进一步了解。
Abstract层
- 之前说过,Abstract层是对业务接口的定义,所以我们新建接口文件IS_UserRepository,定义增删改查业务的接口。这一层需要添加对Entities层的引用。代码如下:
using Entities; using System.Collections.Generic; namespace Abstract { public interface IS_RoleRepository { bool Add(S_Role model); bool Update(S_Role model); bool Delete(long id); List<S_Role> GetInfo(string strWhere, int rows, int page, out int total); } }
Concrete层
- 这一层是对Abstract业务的接口进行实现层,也是利用EntityFramework与数据库进行交互的层。我们定义类文件S_ RoleRepository,实现增删改查业务。查询时,我们将禁用延迟加载。这一层需要添加对Entities、Abstract层的引用。代码如下:
using System.Collections.Generic; using System.Linq; using Abstract; using Entities; namespace Concrete { public class S_RoleRepository : IS_RoleRepository { private EFDbContext context = new EFDbContext(); public bool Add(S_Role model) { try { if (null != model) { context.S_Roles.Add(model); context.SaveChanges(); return true; } else { return false; } } catch { return false; } } public bool Update(S_Role model) { try { if (null != model) { S_Role oldModel = context.S_Roles.FirstOrDefault(x => x.ID == model.ID); oldModel.RoleName = model.RoleName; oldModel.Remark = model.Remark; context.SaveChanges(); return true; } else { return false; } } catch { return false; } } public bool Delete(long id) { try { if (id != 0) { S_Role model = context.S_Roles.FirstOrDefault(x => x.ID == id); if (null != model) { context.S_Roles.Remove(model); context.SaveChanges(); return true; } else { return false; } } else { return false; } } catch { return false; } } public List<S_Role> GetInfo(string strWhere, int rows, int page, out int total) { context.Configuration.ProxyCreationEnabled = false; context.Configuration.LazyLoadingEnabled = false; List<S_Role> listData = new List<S_Role>(); if (!string.IsNullOrEmpty(strWhere)) { listData = context.S_Roles.Where(x => x.RoleName.Contains(strWhere)).ToList(); } else { listData = context.S_Roles.ToList(); } var results = listData.OrderByDescending(p => p.ID).Skip((page - 1) * rows).Take(rows); total = listData.Count(); return results.ToList(); } } }
利用Ninject实现依赖注入
- Ninject是.net平台下的一个IOC/DI框架。在此我们可以利用它解除Concrete对Abstract的强依赖关系。我们通过Ninject可以在web层构建一个依赖注入列表,这样可以在运行时进行依赖呢,而不是在编译时就产生依赖关系。
- 接下来,我们为Web层添加Ninject,可以在Nuget上通过“程序包管理器控制台”进行下载安装。如下图:
- 在Web层建立Infrastructure文件夹,添加NinjectControllerFactory类,实现Concrete和Abstract的动态绑定,在这里我们采用的是Ninject的构造注入的方式。这一层需要添加对Abstract、Concrete的引用。代码如下:
using Abstract; using Concrete; using Ninject; using System; using System.Web.Mvc; using System.Web.Routing; namespace Web.Controllers { public class NinjectControllerFactory : DefaultControllerFactory { private IKernel ninjectKernel; public NinjectControllerFactory() { ninjectKernel = new StandardKernel(); AddBindings(); } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType); } private void AddBindings() { // put additional bindings here ninjectKernel.Bind<IS_RoleRepository >().To<S_ RoleRepository >(); } } }
- 打开Web层的Global.asax文件,添加对动态生成控制器工厂类NinjectControllerFactory的注册。代码如下:
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); DatabaseInitializer.Initialize(); ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory()); } }
实现Web层角色管理界面功能
- 注意:本示例都将采用Jquery的Ajax的异步方式,视图和控制器都将采用Json字符串作为传输对象。如果对这两块不清楚,可以先查阅相关资料了解一下。
- 我们先定义MVC的Models层,新增mod_S_Role类,用于EasyUI的datagrid绑定role对象和分页操作。代码如下:
using Entities; using System.Collections.Generic; namespace Web.Models { public class mod_S_RolePage { public string total { get; set; } public List<S_Role> rows { get; set; } } }
- 再完成MVC的Controllers,新增SystemController控制器,添加角色操作界面视图RoleList,完成SystemController的角色操作代码。代码如下:
using System.Collections.Generic; using System.Web.Mvc; using Abstract; using Common; using Entities; using Web.Models; namespace Web.Controllers { public class SystemController : Controller { private IS_RoleRepository IS_Role; public SystemController(IS_RoleRepository _S_Role) { this.IS_Role = _S_Role; } #region log20150703 Create By Jack: 系统角色操作 public ActionResult RoleList() { return View(); } public ActionResult GetRoles(string strWhere, int rows, int page = 1) { mod_S_RolePage DataModel = new mod_S_RolePage(); int total; //必须定义参数变量接收out参数 List<S_Role> listData = IS_Role.GetInfo(strWhere, rows, page, out total); DataModel.total = total.ToString(); DataModel.rows = listData; return Json(DataModel, JsonRequestBehavior.AllowGet); } public ActionResult CreateRole(S_Role dataModel) { bool rtnFalg = false; if (Request.IsAjaxRequest()) { if (dataModel.ID == 0) //0为ID的默认值 { dataModel.ID = NewID.NewComb(); rtnFalg = IS_Role.Add(dataModel); } else { rtnFalg = IS_Role.Update(dataModel); } if (rtnFalg == true) { return Json(new { flag = true }); } else { return Json(new { flag = false }); } } else { return Json(new { flag = false }); } } [HttpPost] public ActionResult DeleteRole(long id) { if (id != 0) { bool rtnFlag = IS_Role.Delete(id); if (rtnFlag == true) { return Json(new { flag = true }); } else { return Json(new { flag = false }); } } else { return Json(new { flag = false }); } } #endregion } }
- 完成MVC的Views,修改RoleList的代码如下:
@{ ViewBag.Title = "RoleList"; } <script src="~/JSFunction/System_RoleList.js"></script> <div id="toolbar"> <table cellpadding="2"> <tr> <td>角色ID:<input type="hidden" id="hid_optype" name="hid_optype" value="" /></td> <td><input class="easyui-validatebox textbox" type="text" name="ID" disabled="disabled"></input></td> <td>角色名称:</td> <td><input class="easyui-validatebox textbox" type="text" name="RoleName" id="txt_RoleName"></input></td> </tr> </table> <div class="panelExten"> <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-search" plain="true" onclick="ConditionSearch();">查询</a> | <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-add" plain="true" onclick="NewData();">新增</a> | <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-edit" plain="true" onclick="EditData();">编辑</a> | <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-remove" plain="true" onclick="DestroyData();">删除</a> | <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-undo" plain="true" onclick="ClearQuery();">清除</a> </div> </div> <table id="dg" class="easyui-datagrid" pagination="true" rownumbers="true" fit="true" fitcolumns="true" singleselect="true" toolbar="#toolbar" fit="false" style=" height:500px;"> <thead> <tr> <th data-options="field:'ck',checkbox:true"></th> <th field="ID" width="50"> 主键ID </th> <th field="RoleName" width="50"> 角色名称 </th> <th field="Remark" width="150"> 备注 </th> </tr> </thead> </table> <div id="dlg" class="easyui-dialog" style="width: 550px; height: 480px; padding: 10px 20px" closed="true" buttons="#dlg-buttons" modal="true"> <form id="fm" method="post" novalidate> <div class="fitem" style=" display:none;"> <label> 主键ID:</label> <input id="ID" name="ID" class="easyui-validatebox" required="true"> </div> <div class="fitem"> <label>角色名称:</label> <input id="RoleName" name="RoleName" class="easyui-validatebox" required="true"> </div> <div class="fitem"> <label>备注:</label> <textarea id="Remark" name="Remark" cols="50" rows="4"> </textarea> </div> </form> </div> <div id="dlg-buttons"> <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-ok" id="send" onclick="SaveData()"> 保存</a> <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-cancel" onclick="javascript:$('#dlg').dialog('close')">取消</a> </div>
- 注意,由于页面都是由大量的JS代码操作,所以我们在WEB的目录下建立一个JSFunction文件夹来存放页面的处理函数,名字由控制器和视图组合而成,如本例中为System_RoleList.js。代码如下:
//页面加载时读取数据 $(function () { Search(); var dg = $('#dg'); var opts = dg.datagrid('options'); var pager = dg.datagrid('getPager'); pager.pagination({ onSelectPage: function (pageNum, pageSize) { opts.pageNumber = pageNum; opts.pageSize = pageSize; pager.pagination('refresh', { pageNumber: pageNum, pageSize: pageSize }); Search(); //从数据库中获取数据,并加载 }, pageList: [10, 20, 50], //可以设置每页记录条数的列表 beforePageText: '第', //页数文本框前显示的汉字 afterPageText: '页 共 {pages} 页', displayMsg: '当前显示 {from} - {to} 条记录 共 {total} 条记录' }); }); //从数据库中获取数据,并加载 function Search() { var page_Number = $('#dg').datagrid('options').pageNumber; //pageNumber为datagrid的当前页码 var page_Size = $('#dg').datagrid('options').pageSize; //pageSize为datagrid的每页记录条数 var optype = $('#hid_optype').val(); $('#dg').datagrid("loading"); //根据操作类型判断筛选条件 var strRoleName = $('#txt_RoleName').val(); var strWhere = strRoleName; $.post('/System/GetRoles', { strWhere: strWhere, page: page_Number, rows: page_Size }, function (data) { $('#dg').datagrid('loadData', data); $('#dg').datagrid("loaded"); }) } function ConditionSearch() { $('#hid_optype').val(2); //操作:点击查询按钮筛选条件 Search(); } function NewData() { $('#dlg').dialog('open').dialog('setTitle', '新增角色信息'); $('#fm').form('clear'); } function EditData() { var row = $('#dg').datagrid('getSelected'); if (row) { $('#dlg').dialog('open').dialog('setTitle', '编辑角色信息'); $('#fm').form('load', row); } } function DestroyData() { var row = $('#dg').datagrid('getSelected'); if (row) { $.messager.confirm('提醒', '确定删除这条数据吗?', function (r) { if (r) { var strWhere = row.ID; alert(strWhere); $.ajax({ url: '/System/DeleteRole', type: 'POST', data: { id: strWhere }, success: function (data) { var t = data.flag; if (t) { $.messager.show({ title: '提示信息', msg: '【系统提示】:操作成功!', style: { right: '', top: document.body.scrollTop + document.documentElement.scrollTop, bottom: '' } }); //$('#dg_CommGreen').datagrid('reload'); // reload the user data Search(); } } }) } }); } else { $.messager.show({ title: '提示信息', msg: '【系统提示】:请选择须要操作的数据!', style: { right: '', top: document.body.scrollTop + document.documentElement.scrollTop, bottom: '' } }); } } function ClearQuery() { $('#txt_RoleName').val(""); } function SaveData() { var prod = { ID: $('#ID').val(), RoleName: $('#RoleName').val(), Remark: $('#Remark').val() }; $.ajax({ url: '/System/CreateRole', type: 'POST', data: JSON.stringify(prod), dataType: 'json', processData: false, contentType: 'application/json;charset=utf-8', complete: function (data) { $('#dlg').dialog('close'); // close the dialog $('#dg').datagrid('reload'); // reload the user data }, success: function (data) { var t = data.flag; if (t) { $.messager.show({ title: '提示信息', msg: '【系统提示】:操作成功!', style: { right: '', top: document.body.scrollTop + document.documentElement.scrollTop, bottom: '' } }); Search(); //添加成功后加载数据 } else { $.messager.show({ title: '提示信息', msg: '【系统提示】:操作失败!', style: { right: '', top: document.body.scrollTop + document.documentElement.scrollTop, bottom: '' } }); } }, error: function () { $.messager.show({ title: '提示信息', msg: '【系统提示】:操作失败!', style: { right: '', top: document.body.scrollTop + document.documentElement.scrollTop, bottom: '' } }); } }); }
- 到此,角色管理模块功能完成,运行结果如下:
备注
- 本示例按照系统框架的层级结构对系统角色管理模块进行代码的编写。完成了基本功能,但没有对EasyUI做过多详细的解释,有关EasyUI的详细使用方法可以查看官方API。 本示例源码下载。通过运行Account控制器下的Login视图查看系统运行效果: